mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 15:03:57 +08:00
fix(team): use session-id instead of team-name in team_msg across all skills
Root cause: team_msg --team parameter maps directly to filesystem path
.workflow/.team/{value}/.msg/, so using team-name creates wrong directory.
Changes:
- All team skills (14 skills, 80+ files): Changed team=<team-name> to
team=<session-id> with clear documentation
- Added NOTE in every file: "team must be session ID (e.g., TLS-xxx-date),
NOT team name. Extract from Session: field in task description."
- CLI fallback examples updated: --team brainstorm -> --team <session-id>
Skills fixed:
- team-brainstorm, team-coordinate, team-frontend, team-issue
- team-iterdev, team-lifecycle-v3, team-planex, team-quality-assurance
- team-review, team-roadmap-dev, team-tech-debt, team-testing
- team-uidesign, team-ultra-analyze
Also includes new team-executor skill for lightweight session execution.
This commit is contained in:
@@ -101,8 +101,9 @@ Every worker executes the same task discovery flow on startup:
|
|||||||
Standard reporting flow after task completion:
|
Standard reporting flow after task completion:
|
||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Parameters: operation="log", team="brainstorm", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Parameters: operation="log", team=**<session-id>**, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable → `ccw team log --team brainstorm --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **CLI fallback**: When MCP unavailable → `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
||||||
|
- **Note**: `team` must be session ID (e.g., `BRS-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
||||||
3. **TaskUpdate**: Mark task completed
|
3. **TaskUpdate**: Mark task completed
|
||||||
4. **Loop**: Return to Phase 1 to check next task
|
4. **Loop**: Return to Phase 1 to check next task
|
||||||
@@ -142,9 +143,11 @@ All outputs must carry `[role_name]` prefix in both SendMessage content/summary
|
|||||||
|
|
||||||
Every SendMessage **before**, must call `mcp__ccw-tools__team_msg` to log:
|
Every SendMessage **before**, must call `mcp__ccw-tools__team_msg` to log:
|
||||||
|
|
||||||
**Parameters**: operation="log", team="brainstorm", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
**Parameters**: operation="log", team=**<session-id>**, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
|
|
||||||
**CLI fallback**: When MCP unavailable → `ccw team log --team brainstorm --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
**CLI fallback**: When MCP unavailable → `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
||||||
|
|
||||||
|
**Note**: `team` must be session ID (e.g., `BRS-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**Message types by role**:
|
**Message types by role**:
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: **<session-id>**, // MUST be session ID (e.g., BRS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "challenger",
|
from: "challenger",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "critique_ready",
|
type: "critique_ready",
|
||||||
@@ -71,7 +71,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from challenger --to coordinator --type critique_ready --summary \"[challenger] Critique complete\" --ref <output-path> --json")
|
Bash("ccw team log --team <session-id> --from challenger --to coordinator --type critique_ready --summary \"[challenger] Critique complete\" --ref <output-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: **<session-id>**, // MUST be session ID (e.g., BRS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "coordinator",
|
from: "coordinator",
|
||||||
to: <recipient>,
|
to: <recipient>,
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -59,7 +59,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from coordinator --to <recipient> --type <message-type> --summary \"[coordinator] <action> complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from coordinator --to <recipient> --type <message-type> --summary \"[coordinator] <action> complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: **<session-id>**, // MUST be session ID (e.g., BRS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "evaluator",
|
from: "evaluator",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "evaluation_ready",
|
type: "evaluation_ready",
|
||||||
@@ -72,7 +72,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from evaluator --to coordinator --type evaluation_ready --summary \"[evaluator] Evaluation complete\" --ref <output-path> --json")
|
Bash("ccw team log --team <session-id> --from evaluator --to coordinator --type evaluation_ready --summary \"[evaluator] Evaluation complete\" --ref <output-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: **<session-id>**, // MUST be session ID (e.g., BRS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "ideator",
|
from: "ideator",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <ideas_ready|ideas_revised>,
|
type: <ideas_ready|ideas_revised>,
|
||||||
@@ -72,7 +72,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from ideator --to coordinator --type <message-type> --summary \"[ideator] ideas complete\" --ref <output-path> --json")
|
Bash("ccw team log --team <session-id> --from ideator --to coordinator --type <message-type> --summary \"[ideator] ideas complete\" --ref <output-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: **<session-id>**, // MUST be session ID (e.g., BRS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "synthesizer",
|
from: "synthesizer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "synthesis_ready",
|
type: "synthesis_ready",
|
||||||
@@ -72,7 +72,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from synthesizer --to coordinator --type synthesis_ready --summary \"[synthesizer] Synthesis complete\" --ref <output-path> --json")
|
Bash("ccw team log --team <session-id> --from synthesizer --to coordinator --type synthesis_ready --summary \"[synthesizer] Synthesis complete\" --ref <output-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -66,8 +66,10 @@ Only coordinator is statically registered. All other roles are dynamic, stored i
|
|||||||
1. Extract `--role` and `--session` from arguments
|
1. Extract `--role` and `--session` from arguments
|
||||||
2. If no `--role` -> route to coordinator (Orchestration Mode)
|
2. If no `--role` -> route to coordinator (Orchestration Mode)
|
||||||
3. If `--role=coordinator` -> Read built-in `roles/coordinator/role.md` -> Execute its phases
|
3. If `--role=coordinator` -> Read built-in `roles/coordinator/role.md` -> Execute its phases
|
||||||
4. If `--role=<other>` -> Read `<session>/roles/<role>.md` -> Execute its phases
|
4. If `--role=<other>`:
|
||||||
5. If session path not provided -> auto-discover from `.workflow/.team/TC-*/team-session.json`
|
- **`--session` is REQUIRED** for dynamic roles. Error if not provided.
|
||||||
|
- Read `<session>/roles/<role>.md` -> Execute its phases
|
||||||
|
- If role file not found at path -> Error with expected path
|
||||||
|
|
||||||
### Orchestration Mode
|
### Orchestration Mode
|
||||||
|
|
||||||
@@ -118,8 +120,9 @@ Each worker on startup executes the same task discovery flow:
|
|||||||
Task completion with optional fast-advance to skip coordinator round-trip:
|
Task completion with optional fast-advance to skip coordinator round-trip:
|
||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Params: operation="log", team=<team-name>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Params: operation="log", team=**<session-id>**, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable -> `ccw team log --team <team> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **`team` must be session ID** (e.g., `TC-my-project-2026-02-27`), NOT team name. Extract from task description `Session:` field -> take folder name.
|
||||||
|
- **CLI fallback**: `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
||||||
2. **TaskUpdate**: Mark task completed
|
2. **TaskUpdate**: Mark task completed
|
||||||
3. **Fast-Advance Check**:
|
3. **Fast-Advance Check**:
|
||||||
- Call `TaskList()`, find pending tasks whose blockedBy are ALL completed
|
- Call `TaskList()`, find pending tasks whose blockedBy are ALL completed
|
||||||
@@ -309,13 +312,13 @@ Session: <session-folder>
|
|||||||
- All output prefixed with [<role>] tag
|
- All output prefixed with [<role>] tag
|
||||||
- Only communicate with coordinator
|
- Only communicate with coordinator
|
||||||
- Do not use TaskCreate to create tasks for other roles
|
- Do not use TaskCreate to create tasks for other roles
|
||||||
- Before each SendMessage, call mcp__ccw-tools__team_msg to log
|
- Before each SendMessage, call mcp__ccw-tools__team_msg to log (team=<session-id> from Session field, NOT team name)
|
||||||
- After task completion, check for fast-advance opportunity (see SKILL.md Phase 5)
|
- After task completion, check for fast-advance opportunity (see SKILL.md Phase 5)
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
1. Call Skill -> get role definition and execution logic
|
1. Call Skill -> get role definition and execution logic
|
||||||
2. Follow role.md 5-Phase flow
|
2. Follow role.md 5-Phase flow
|
||||||
3. team_msg + SendMessage results to coordinator
|
3. team_msg(team=<session-id>) + SendMessage results to coordinator
|
||||||
4. TaskUpdate completed -> check next task or fast-advance`
|
4. TaskUpdate completed -> check next task or fast-advance`
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -351,7 +354,7 @@ Only SendMessage to coordinator when:
|
|||||||
- All output prefixed with [<role>] tag
|
- All output prefixed with [<role>] tag
|
||||||
- Only communicate with coordinator
|
- Only communicate with coordinator
|
||||||
- Do not use TaskCreate to create tasks for other roles
|
- Do not use TaskCreate to create tasks for other roles
|
||||||
- Before each SendMessage, call mcp__ccw-tools__team_msg to log
|
- Before each SendMessage, call mcp__ccw-tools__team_msg to log (team=<session-id> from Session field, NOT team name)
|
||||||
- Use subagent calls for heavy work, retain summaries in context`
|
- Use subagent calls for heavy work, retain summaries in context`
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -438,5 +441,5 @@ Coordinator supports `--resume` / `--continue` for interrupted sessions:
|
|||||||
| Discuss subagent fails | Role proceeds without discuss, logs warning |
|
| Discuss subagent fails | Role proceeds without discuss, logs warning |
|
||||||
| Explore cache corrupt | Clear cache, re-explore |
|
| Explore cache corrupt | Clear cache, re-explore |
|
||||||
| Fast-advance spawns wrong task | Coordinator reconciles on next callback |
|
| Fast-advance spawns wrong task | Coordinator reconciles on next callback |
|
||||||
| Session path not provided | Auto-discover from `.workflow/.team/TC-*/team-session.json` |
|
| Session path not provided (dynamic role) | Error: `--session` is required for dynamic roles. Coordinator must always pass `--session=<session-folder>` when spawning workers. |
|
||||||
| capability_gap reported | Coordinator generates new role via handleAdapt |
|
| capability_gap reported | Coordinator generates new role via handleAdapt |
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ Ready tasks found?
|
|||||||
| +- YES -> SKIP spawn (existing worker will pick it up via inner loop)
|
| +- YES -> SKIP spawn (existing worker will pick it up via inner loop)
|
||||||
| +- NO -> normal spawn below
|
| +- NO -> normal spawn below
|
||||||
+- TaskUpdate -> in_progress
|
+- TaskUpdate -> in_progress
|
||||||
+- team_msg log -> task_unblocked
|
+- team_msg log -> task_unblocked (team=<session-id>, NOT team name)
|
||||||
+- Spawn worker (see spawn tool call below)
|
+- Spawn worker (see spawn tool call below)
|
||||||
+- Add to session.active_workers
|
+- Add to session.active_workers
|
||||||
Update session file -> output summary -> STOP
|
Update session file -> output summary -> STOP
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: <session-id>,
|
||||||
from: "<role_name>",
|
from: "<role_name>",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -75,10 +75,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**`team` must be session ID** (e.g., `TC-my-project-2026-02-27`), NOT team name. Extract from task description `Session:` field -> take folder name.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from <role_name> --to coordinator --type <message-type> --summary \"[<role_name>] <prefix> complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from <role_name> --to coordinator --type <message-type> --summary \"[<role_name>] <prefix> complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
372
.claude/skills/team-executor/SKILL.md
Normal file
372
.claude/skills/team-executor/SKILL.md
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
---
|
||||||
|
name: team-executor
|
||||||
|
description: Lightweight session execution skill. Resumes existing team-coordinate sessions for pure execution. No analysis, no role generation -- only loads and executes. Session path required. Triggers on "team executor".
|
||||||
|
allowed-tools: TeamCreate(*), TeamDelete(*), SendMessage(*), TaskCreate(*), TaskUpdate(*), TaskList(*), TaskGet(*), Task(*), AskUserQuestion(*), Read(*), Write(*), Edit(*), Bash(*), Glob(*), Grep(*)
|
||||||
|
---
|
||||||
|
|
||||||
|
# Team Executor
|
||||||
|
|
||||||
|
Lightweight session execution skill: load session -> reconcile state -> spawn workers -> execute -> deliver. **No analysis, no role generation** -- only executes existing team-coordinate sessions.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
+---------------------------------------------------+
|
||||||
|
| Skill(skill="team-executor") |
|
||||||
|
| args="--session=<path>" [REQUIRED] |
|
||||||
|
| args="--role=<name>" (for worker dispatch) |
|
||||||
|
+-------------------+-------------------------------+
|
||||||
|
| Session Validation
|
||||||
|
+---- --session valid? ----+
|
||||||
|
| NO | YES
|
||||||
|
v v
|
||||||
|
Error immediately Role Router
|
||||||
|
(no session) |
|
||||||
|
+-------+-------+
|
||||||
|
| --role present?
|
||||||
|
| |
|
||||||
|
YES | | NO
|
||||||
|
v | v
|
||||||
|
Route to | Orchestration Mode
|
||||||
|
session | -> executor
|
||||||
|
role.md |
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session Validation (BEFORE routing)
|
||||||
|
|
||||||
|
**CRITICAL**: Session validation MUST occur before any role routing.
|
||||||
|
|
||||||
|
### Parse Arguments
|
||||||
|
|
||||||
|
Extract from `$ARGUMENTS`:
|
||||||
|
- `--session=<path>`: Path to team-coordinate session folder (REQUIRED)
|
||||||
|
- `--role=<name>`: Role to dispatch (optional, defaults to orchestration mode)
|
||||||
|
|
||||||
|
### Validation Steps
|
||||||
|
|
||||||
|
1. **Check `--session` provided**:
|
||||||
|
- If missing -> **ERROR**: "Session required. Usage: --session=<path-to-TC-folder>"
|
||||||
|
- Do NOT proceed
|
||||||
|
|
||||||
|
2. **Validate session structure** (see specs/session-schema.md):
|
||||||
|
- Directory exists at path
|
||||||
|
- `team-session.json` exists and valid JSON
|
||||||
|
- `task-analysis.json` exists and valid JSON
|
||||||
|
- `roles/` directory has at least one `.md` file
|
||||||
|
- Each role in `team-session.json#roles` has corresponding `.md` file in `roles/`
|
||||||
|
|
||||||
|
3. **Validation failure**:
|
||||||
|
- Report specific missing component
|
||||||
|
- Suggest re-running team-coordinate or checking path
|
||||||
|
- Do NOT proceed
|
||||||
|
|
||||||
|
### Validation Checklist
|
||||||
|
|
||||||
|
```
|
||||||
|
Session Validation Checklist:
|
||||||
|
[ ] --session argument provided
|
||||||
|
[ ] Directory exists at path
|
||||||
|
[ ] team-session.json exists and parses
|
||||||
|
[ ] task-analysis.json exists and parses
|
||||||
|
[ ] roles/ directory has >= 1 .md files
|
||||||
|
[ ] All session.roles[] have corresponding roles/<role>.md
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Role Router
|
||||||
|
|
||||||
|
### Dispatch Logic
|
||||||
|
|
||||||
|
| Scenario | Action |
|
||||||
|
|----------|--------|
|
||||||
|
| No `--session` | **ERROR** immediately |
|
||||||
|
| `--session` invalid | **ERROR** with specific reason |
|
||||||
|
| No `--role` | Orchestration Mode -> executor |
|
||||||
|
| `--role=executor` | Read built-in `roles/executor/role.md` |
|
||||||
|
| `--role=<other>` | Read `<session>/roles/<role>.md` |
|
||||||
|
|
||||||
|
### Orchestration Mode
|
||||||
|
|
||||||
|
When invoked without `--role`, executor auto-starts.
|
||||||
|
|
||||||
|
**Invocation**: `Skill(skill="team-executor", args="--session=<session-folder>")`
|
||||||
|
|
||||||
|
**Lifecycle**:
|
||||||
|
```
|
||||||
|
Validate session
|
||||||
|
-> executor Phase 0: Reconcile state (reset interrupted, detect orphans)
|
||||||
|
-> executor Phase 1: Spawn first batch workers (background) -> STOP
|
||||||
|
-> Worker executes -> SendMessage callback -> executor advances next step
|
||||||
|
-> Loop until pipeline complete -> Phase 2 report
|
||||||
|
```
|
||||||
|
|
||||||
|
**User Commands** (wake paused executor):
|
||||||
|
|
||||||
|
| Command | Action |
|
||||||
|
|---------|--------|
|
||||||
|
| `check` / `status` | Output execution status graph, no advancement |
|
||||||
|
| `resume` / `continue` | Check worker states, advance next step |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Role Registry
|
||||||
|
|
||||||
|
| Role | File | Type |
|
||||||
|
|------|------|------|
|
||||||
|
| executor | [roles/executor/role.md](roles/executor/role.md) | built-in orchestrator |
|
||||||
|
| (dynamic) | `<session>/roles/<role-name>.md` | loaded from session |
|
||||||
|
|
||||||
|
> **COMPACT PROTECTION**: Role files are execution documents. After context compression, role instructions become summaries only -- **MUST immediately `Read` the role.md to reload before continuing**. Never execute any Phase based on summaries.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shared Infrastructure
|
||||||
|
|
||||||
|
The following templates apply to all worker roles. Each loaded role.md follows the same structure.
|
||||||
|
|
||||||
|
### Worker Phase 1: Task Discovery (all workers shared)
|
||||||
|
|
||||||
|
Each worker on startup executes the same task discovery flow:
|
||||||
|
|
||||||
|
1. Call `TaskList()` to get all tasks
|
||||||
|
2. Filter: subject matches this role's prefix + owner is this role + status is pending + blockedBy is empty
|
||||||
|
3. No tasks -> idle wait
|
||||||
|
4. Has tasks -> `TaskGet` for details -> `TaskUpdate` mark in_progress
|
||||||
|
|
||||||
|
**Resume Artifact Check** (prevent duplicate output after resume):
|
||||||
|
- Check if this task's output artifacts already exist
|
||||||
|
- Artifacts complete -> skip to Phase 5 report completion
|
||||||
|
- Artifacts incomplete or missing -> normal Phase 2-4 execution
|
||||||
|
|
||||||
|
### Worker Phase 5: Report + Fast-Advance (all workers shared)
|
||||||
|
|
||||||
|
Task completion with optional fast-advance to skip executor round-trip:
|
||||||
|
|
||||||
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
|
- Params: operation="log", team=**<session-id>**, from=<role>, to="executor", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
|
- **`team` must be session ID** (e.g., `TC-my-project-2026-02-27`), NOT team name. Extract from task description `Session:` field -> take folder name.
|
||||||
|
- **CLI fallback**: `ccw team log --team <session-id> --from <role> --to executor --type <type> --summary "[<role>] ..." --json`
|
||||||
|
2. **TaskUpdate**: Mark task completed
|
||||||
|
3. **Fast-Advance Check**:
|
||||||
|
- Call `TaskList()`, find pending tasks whose blockedBy are ALL completed
|
||||||
|
- If exactly 1 ready task AND its owner matches a simple successor pattern -> **spawn it directly** (skip executor)
|
||||||
|
- Otherwise -> **SendMessage** to executor for orchestration
|
||||||
|
4. **Loop**: Back to Phase 1 to check for next task
|
||||||
|
|
||||||
|
**Fast-Advance Rules**:
|
||||||
|
|
||||||
|
| Condition | Action |
|
||||||
|
|-----------|--------|
|
||||||
|
| Same-prefix successor (Inner Loop role) | Do not spawn, main agent inner loop (Phase 5-L) |
|
||||||
|
| 1 ready task, simple linear successor, different prefix | Spawn directly via Task(run_in_background: true) |
|
||||||
|
| Multiple ready tasks (parallel window) | SendMessage to executor (needs orchestration) |
|
||||||
|
| No ready tasks + others running | SendMessage to executor (status update) |
|
||||||
|
| No ready tasks + nothing running | SendMessage to executor (pipeline may be complete) |
|
||||||
|
|
||||||
|
**Fast-advance failure recovery**: If a fast-advanced task fails, the executor detects it as an orphaned in_progress task on next `resume`/`check` and resets it to pending for re-spawn. Self-healing. See [monitor.md](roles/executor/commands/monitor.md).
|
||||||
|
|
||||||
|
### Worker Inner Loop (roles with multiple same-prefix serial tasks)
|
||||||
|
|
||||||
|
When a role has **2+ serial same-prefix tasks**, it loops internally instead of spawning new agents:
|
||||||
|
|
||||||
|
**Inner Loop flow**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Phase 1: Discover task (first time)
|
||||||
|
|
|
||||||
|
+- Found task -> Phase 2-3: Load context + Execute work
|
||||||
|
| |
|
||||||
|
| v
|
||||||
|
| Phase 4: Validation (+ optional Inline Discuss)
|
||||||
|
| |
|
||||||
|
| v
|
||||||
|
| Phase 5-L: Loop Completion
|
||||||
|
| |
|
||||||
|
| +- TaskUpdate completed
|
||||||
|
| +- team_msg log
|
||||||
|
| +- Accumulate summary to context_accumulator
|
||||||
|
| |
|
||||||
|
| +- More same-prefix tasks?
|
||||||
|
| | +- YES -> back to Phase 1 (inner loop)
|
||||||
|
| | +- NO -> Phase 5-F: Final Report
|
||||||
|
| |
|
||||||
|
| +- Interrupt conditions?
|
||||||
|
| +- consensus_blocked HIGH -> SendMessage -> STOP
|
||||||
|
| +- Errors >= 3 -> SendMessage -> STOP
|
||||||
|
|
|
||||||
|
+- Phase 5-F: Final Report
|
||||||
|
+- SendMessage (all task summaries)
|
||||||
|
+- STOP
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 5-L vs Phase 5-F**:
|
||||||
|
|
||||||
|
| Step | Phase 5-L (looping) | Phase 5-F (final) |
|
||||||
|
|------|---------------------|-------------------|
|
||||||
|
| TaskUpdate completed | YES | YES |
|
||||||
|
| team_msg log | YES | YES |
|
||||||
|
| Accumulate summary | YES | - |
|
||||||
|
| SendMessage to executor | NO | YES (all tasks summary) |
|
||||||
|
| Fast-Advance to next prefix | - | YES (check cross-prefix successors) |
|
||||||
|
|
||||||
|
### Wisdom Accumulation (all roles)
|
||||||
|
|
||||||
|
Cross-task knowledge accumulation. Loaded from session at startup.
|
||||||
|
|
||||||
|
**Directory**:
|
||||||
|
```
|
||||||
|
<session-folder>/wisdom/
|
||||||
|
+-- learnings.md # Patterns and insights
|
||||||
|
+-- decisions.md # Design and strategy decisions
|
||||||
|
+-- issues.md # Known risks and issues
|
||||||
|
```
|
||||||
|
|
||||||
|
**Worker load** (Phase 2): Extract `Session: <path>` from task description, read wisdom files.
|
||||||
|
**Worker contribute** (Phase 4/5): Write discoveries to corresponding wisdom files.
|
||||||
|
|
||||||
|
### Role Isolation Rules
|
||||||
|
|
||||||
|
| Allowed | Prohibited |
|
||||||
|
|---------|-----------|
|
||||||
|
| Process own prefix tasks | Process other role's prefix tasks |
|
||||||
|
| SendMessage to executor | Directly communicate with other workers |
|
||||||
|
| Use tools appropriate to responsibility | Create tasks for other roles |
|
||||||
|
| Fast-advance simple successors | Spawn parallel worker batches |
|
||||||
|
| Report capability_gap to executor | Attempt work outside scope |
|
||||||
|
|
||||||
|
Executor additionally prohibited: directly write/modify deliverable artifacts, call implementation subagents directly, directly execute analysis/test/review, generate new roles.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cadence Control
|
||||||
|
|
||||||
|
**Beat model**: Event-driven, each beat = executor wake -> process -> spawn -> STOP.
|
||||||
|
|
||||||
|
```
|
||||||
|
Beat Cycle (single beat)
|
||||||
|
======================================================================
|
||||||
|
Event Executor Workers
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
callback/resume --> +- handleCallback -+
|
||||||
|
| mark completed |
|
||||||
|
| check pipeline |
|
||||||
|
+- handleSpawnNext -+
|
||||||
|
| find ready tasks |
|
||||||
|
| spawn workers ---+--> [Worker A] Phase 1-5
|
||||||
|
| (parallel OK) --+--> [Worker B] Phase 1-5
|
||||||
|
+- STOP (idle) -----+ |
|
||||||
|
|
|
||||||
|
callback <-----------------------------------------+
|
||||||
|
(next beat) SendMessage + TaskUpdate(completed)
|
||||||
|
======================================================================
|
||||||
|
|
||||||
|
Fast-Advance (skips executor for simple linear successors)
|
||||||
|
======================================================================
|
||||||
|
[Worker A] Phase 5 complete
|
||||||
|
+- 1 ready task? simple successor? --> spawn Worker B directly
|
||||||
|
+- complex case? --> SendMessage to executor
|
||||||
|
======================================================================
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executor Spawn Template
|
||||||
|
|
||||||
|
### Standard Worker (single-task role)
|
||||||
|
|
||||||
|
```
|
||||||
|
Task({
|
||||||
|
subagent_type: "general-purpose",
|
||||||
|
description: "Spawn <role> worker",
|
||||||
|
team_name: <team-name>,
|
||||||
|
name: "<role>",
|
||||||
|
run_in_background: true,
|
||||||
|
prompt: `You are team "<team-name>" <ROLE>.
|
||||||
|
|
||||||
|
## Primary Instruction
|
||||||
|
All your work MUST be executed by calling Skill to get role definition:
|
||||||
|
Skill(skill="team-executor", args="--role=<role> --session=<session-folder>")
|
||||||
|
|
||||||
|
Current requirement: <task-description>
|
||||||
|
Session: <session-folder>
|
||||||
|
|
||||||
|
## Role Guidelines
|
||||||
|
- Only process <PREFIX>-* tasks, do not execute other role work
|
||||||
|
- All output prefixed with [<role>] tag
|
||||||
|
- Only communicate with executor
|
||||||
|
- Do not use TaskCreate to create tasks for other roles
|
||||||
|
- Before each SendMessage, call mcp__ccw-tools__team_msg to log (team=<session-id> from Session field, NOT team name)
|
||||||
|
- After task completion, check for fast-advance opportunity (see SKILL.md Phase 5)
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
1. Call Skill -> get role definition and execution logic
|
||||||
|
2. Follow role.md 5-Phase flow
|
||||||
|
3. team_msg(team=<session-id>) + SendMessage results to executor
|
||||||
|
4. TaskUpdate completed -> check next task or fast-advance`
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inner Loop Worker (multi-task role)
|
||||||
|
|
||||||
|
```
|
||||||
|
Task({
|
||||||
|
subagent_type: "general-purpose",
|
||||||
|
description: "Spawn <role> worker (inner loop)",
|
||||||
|
team_name: <team-name>,
|
||||||
|
name: "<role>",
|
||||||
|
run_in_background: true,
|
||||||
|
prompt: `You are team "<team-name>" <ROLE>.
|
||||||
|
|
||||||
|
## Primary Instruction
|
||||||
|
All your work MUST be executed by calling Skill to get role definition:
|
||||||
|
Skill(skill="team-executor", args="--role=<role> --session=<session-folder>")
|
||||||
|
|
||||||
|
Current requirement: <task-description>
|
||||||
|
Session: <session-folder>
|
||||||
|
|
||||||
|
## Inner Loop Mode
|
||||||
|
You will handle ALL <PREFIX>-* tasks in this session, not just the first one.
|
||||||
|
After completing each task, loop back to find the next <PREFIX>-* task.
|
||||||
|
Only SendMessage to executor when:
|
||||||
|
- All <PREFIX>-* tasks are done
|
||||||
|
- A consensus_blocked HIGH occurs
|
||||||
|
- Errors accumulate (>= 3)
|
||||||
|
|
||||||
|
## Role Guidelines
|
||||||
|
- Only process <PREFIX>-* tasks, do not execute other role work
|
||||||
|
- All output prefixed with [<role>] tag
|
||||||
|
- Only communicate with executor
|
||||||
|
- Do not use TaskCreate to create tasks for other roles
|
||||||
|
- Before each SendMessage, call mcp__ccw-tools__team_msg to log (team=<session-id> from Session field, NOT team name)
|
||||||
|
- Use subagent calls for heavy work, retain summaries in context`
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Integration with team-coordinate
|
||||||
|
|
||||||
|
| Scenario | Skill |
|
||||||
|
|----------|-------|
|
||||||
|
| New task, no session | team-coordinate |
|
||||||
|
| Existing session, resume execution | **team-executor** |
|
||||||
|
| Session needs new roles | team-coordinate (with --resume) |
|
||||||
|
| Pure execution, no analysis | **team-executor** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| No --session provided | ERROR immediately with usage message |
|
||||||
|
| Session directory not found | ERROR with path, suggest checking path |
|
||||||
|
| team-session.json missing | ERROR, session incomplete, suggest re-run team-coordinate |
|
||||||
|
| task-analysis.json missing | ERROR, session incomplete, suggest re-run team-coordinate |
|
||||||
|
| No roles in session | ERROR, session incomplete, suggest re-run team-coordinate |
|
||||||
|
| Role file not found | ERROR with expected path |
|
||||||
|
| capability_gap reported | Warn only, cannot generate new roles (see monitor.md handleAdapt) |
|
||||||
|
| Fast-advance spawns wrong task | Executor reconciles on next callback |
|
||||||
277
.claude/skills/team-executor/roles/executor/commands/monitor.md
Normal file
277
.claude/skills/team-executor/roles/executor/commands/monitor.md
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
# Command: monitor
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Event-driven pipeline coordination with Spawn-and-Stop pattern for team-executor. Adapted from team-coordinate monitor.md -- role names are read from `team-session.json#roles` instead of hardcoded. **handleAdapt is LIMITED**: only warns, cannot generate new roles.
|
||||||
|
|
||||||
|
## Constants
|
||||||
|
|
||||||
|
| Constant | Value | Description |
|
||||||
|
|----------|-------|-------------|
|
||||||
|
| SPAWN_MODE | background | All workers spawned via `Task(run_in_background: true)` |
|
||||||
|
| ONE_STEP_PER_INVOCATION | true | Executor does one operation then STOPS |
|
||||||
|
| FAST_ADVANCE_AWARE | true | Workers may skip executor for simple linear successors |
|
||||||
|
| ROLE_GENERATION | disabled | handleAdapt cannot generate new roles |
|
||||||
|
|
||||||
|
## Phase 2: Context Loading
|
||||||
|
|
||||||
|
| Input | Source | Required |
|
||||||
|
|-------|--------|----------|
|
||||||
|
| Session file | `<session-folder>/team-session.json` | Yes |
|
||||||
|
| Task list | `TaskList()` | Yes |
|
||||||
|
| Active workers | session.active_workers[] | Yes |
|
||||||
|
| Role registry | session.roles[] | Yes |
|
||||||
|
|
||||||
|
**Dynamic role resolution**: Known worker roles are loaded from `session.roles[].name`. This is the same pattern as team-coordinate.
|
||||||
|
|
||||||
|
## Phase 3: Handler Routing
|
||||||
|
|
||||||
|
### Wake-up Source Detection
|
||||||
|
|
||||||
|
Parse `$ARGUMENTS` to determine handler:
|
||||||
|
|
||||||
|
| Priority | Condition | Handler |
|
||||||
|
|----------|-----------|---------|
|
||||||
|
| 1 | Message contains `[<role-name>]` from session roles | handleCallback |
|
||||||
|
| 2 | Contains "capability_gap" | handleAdapt |
|
||||||
|
| 3 | Contains "check" or "status" | handleCheck |
|
||||||
|
| 4 | Contains "resume", "continue", or "next" | handleResume |
|
||||||
|
| 5 | None of the above (initial spawn after dispatch) | handleSpawnNext |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Handler: handleCallback
|
||||||
|
|
||||||
|
Worker completed a task. Verify completion, update state, auto-advance.
|
||||||
|
|
||||||
|
```
|
||||||
|
Receive callback from [<role>]
|
||||||
|
+- Find matching active worker by role (from session.roles)
|
||||||
|
+- Is this a progress update (not final)? (Inner Loop intermediate task completion)
|
||||||
|
| +- YES -> Update session state, do NOT remove from active_workers -> STOP
|
||||||
|
+- Task status = completed?
|
||||||
|
| +- YES -> remove from active_workers -> update session
|
||||||
|
| | +- -> handleSpawnNext
|
||||||
|
| +- NO -> progress message, do not advance -> STOP
|
||||||
|
+- No matching worker found
|
||||||
|
+- Scan all active workers for completed tasks
|
||||||
|
+- Found completed -> process each -> handleSpawnNext
|
||||||
|
+- None completed -> STOP
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fast-advance note**: A worker may have already spawned its successor via fast-advance. When processing a callback:
|
||||||
|
1. Check if the expected next task is already `in_progress` (fast-advanced)
|
||||||
|
2. If yes -> skip spawning that task, update active_workers to include the fast-advanced worker
|
||||||
|
3. If no -> normal handleSpawnNext
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Handler: handleCheck
|
||||||
|
|
||||||
|
Read-only status report. No pipeline advancement.
|
||||||
|
|
||||||
|
**Output format**:
|
||||||
|
|
||||||
|
```
|
||||||
|
[executor] Pipeline Status
|
||||||
|
[executor] Progress: <completed>/<total> (<percent>%)
|
||||||
|
|
||||||
|
[executor] Execution Graph:
|
||||||
|
<visual representation of dependency graph with status icons>
|
||||||
|
|
||||||
|
done=completed >>>=running o=pending .=not created
|
||||||
|
|
||||||
|
[executor] Active Workers:
|
||||||
|
> <subject> (<role>) - running <elapsed> [inner-loop: N/M tasks done]
|
||||||
|
|
||||||
|
[executor] Ready to spawn: <subjects>
|
||||||
|
[executor] Commands: 'resume' to advance | 'check' to refresh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Icon mapping**: completed=done, in_progress=>>>, pending=o, not created=.
|
||||||
|
|
||||||
|
**Graph rendering**: Read dependency_graph from task-analysis.json, render each node with status icon. Show parallel branches side-by-side.
|
||||||
|
|
||||||
|
Then STOP.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Handler: handleResume
|
||||||
|
|
||||||
|
Check active worker completion, process results, advance pipeline.
|
||||||
|
|
||||||
|
```
|
||||||
|
Load active_workers from session
|
||||||
|
+- No active workers -> handleSpawnNext
|
||||||
|
+- Has active workers -> check each:
|
||||||
|
+- status = completed -> mark done, log
|
||||||
|
+- status = in_progress -> still running, log
|
||||||
|
+- other status -> worker failure -> reset to pending
|
||||||
|
After processing:
|
||||||
|
+- Some completed -> handleSpawnNext
|
||||||
|
+- All still running -> report status -> STOP
|
||||||
|
+- All failed -> handleSpawnNext (retry)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Handler: handleSpawnNext
|
||||||
|
|
||||||
|
Find all ready tasks, spawn workers in background, update session, STOP.
|
||||||
|
|
||||||
|
```
|
||||||
|
Collect task states from TaskList()
|
||||||
|
+- completedSubjects: status = completed
|
||||||
|
+- inProgressSubjects: status = in_progress
|
||||||
|
+- readySubjects: pending + all blockedBy in completedSubjects
|
||||||
|
|
||||||
|
Ready tasks found?
|
||||||
|
+- NONE + work in progress -> report waiting -> STOP
|
||||||
|
+- NONE + nothing in progress -> PIPELINE_COMPLETE -> Phase 2
|
||||||
|
+- HAS ready tasks -> for each:
|
||||||
|
+- Is task owner an Inner Loop role AND that role already has an active_worker?
|
||||||
|
| +- YES -> SKIP spawn (existing worker will pick it up via inner loop)
|
||||||
|
| +- NO -> normal spawn below
|
||||||
|
+- TaskUpdate -> in_progress
|
||||||
|
+- team_msg log -> task_unblocked (team=<session-id>, NOT team name)
|
||||||
|
+- Spawn worker (see spawn tool call below)
|
||||||
|
+- Add to session.active_workers
|
||||||
|
Update session file -> output summary -> STOP
|
||||||
|
```
|
||||||
|
|
||||||
|
**Spawn worker tool call** (one per ready task):
|
||||||
|
|
||||||
|
```
|
||||||
|
Task({
|
||||||
|
subagent_type: "general-purpose",
|
||||||
|
description: "Spawn <role> worker for <subject>",
|
||||||
|
team_name: <team-name>,
|
||||||
|
name: "<role>",
|
||||||
|
run_in_background: true,
|
||||||
|
prompt: "<worker prompt from SKILL.md Executor Spawn Template>"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Handler: handleAdapt (LIMITED)
|
||||||
|
|
||||||
|
Handle mid-pipeline capability gap discovery. **UNLIKE team-coordinate, executor CANNOT generate new roles.**
|
||||||
|
|
||||||
|
```
|
||||||
|
Receive capability_gap from [<role>]
|
||||||
|
+- Log via team_msg (type: warning)
|
||||||
|
+- Report to user:
|
||||||
|
"Capability gap detected: <gap_description>
|
||||||
|
|
||||||
|
team-executor cannot generate new roles.
|
||||||
|
Options:
|
||||||
|
1. Continue with existing roles (worker will skip gap work)
|
||||||
|
2. Re-run team-coordinate with --resume=<session> to extend session
|
||||||
|
3. Manually add role to <session>/roles/ and retry"
|
||||||
|
+- Extract: gap_description, requesting_role, suggested_capability
|
||||||
|
+- Validate gap is genuine:
|
||||||
|
+- Check existing roles in session.roles -> does any role cover this?
|
||||||
|
| +- YES -> redirect: SendMessage to that role's owner -> STOP
|
||||||
|
| +- NO -> genuine gap, report to user (cannot fix)
|
||||||
|
+- Do NOT generate new role
|
||||||
|
+- Continue execution with existing roles
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key difference from team-coordinate**:
|
||||||
|
| Aspect | team-coordinate | team-executor |
|
||||||
|
|--------|-----------------|---------------|
|
||||||
|
| handleAdapt | Generates new role, creates tasks, spawns worker | Only warns, cannot fix |
|
||||||
|
| Recovery | Automatic | Manual (re-run team-coordinate) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Worker Failure Handling
|
||||||
|
|
||||||
|
When a worker has unexpected status (not completed, not in_progress):
|
||||||
|
|
||||||
|
1. Reset task -> pending via TaskUpdate
|
||||||
|
2. Log via team_msg (type: error)
|
||||||
|
3. Report to user: task reset, will retry on next resume
|
||||||
|
|
||||||
|
### Fast-Advance Failure Recovery
|
||||||
|
|
||||||
|
When executor detects a fast-advanced task has failed (task in_progress but no callback and worker gone):
|
||||||
|
|
||||||
|
```
|
||||||
|
handleCallback / handleResume detects:
|
||||||
|
+- Task is in_progress (was fast-advanced by predecessor)
|
||||||
|
+- No active_worker entry for this task
|
||||||
|
+- Original fast-advancing worker has already completed and exited
|
||||||
|
+- Resolution:
|
||||||
|
1. TaskUpdate -> reset task to pending
|
||||||
|
2. Remove stale active_worker entry (if any)
|
||||||
|
3. Log via team_msg (type: error, summary: "Fast-advanced task <ID> failed, resetting for retry")
|
||||||
|
4. -> handleSpawnNext (will re-spawn the task normally)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Detection in handleResume**:
|
||||||
|
|
||||||
|
```
|
||||||
|
For each in_progress task in TaskList():
|
||||||
|
+- Has matching active_worker? -> normal, skip
|
||||||
|
+- No matching active_worker? -> orphaned (likely fast-advance failure)
|
||||||
|
+- Check creation time: if > 5 minutes with no progress callback
|
||||||
|
+- Reset to pending -> handleSpawnNext
|
||||||
|
```
|
||||||
|
|
||||||
|
**Prevention**: Fast-advance failures are self-healing. The executor reconciles orphaned tasks on every `resume`/`check` cycle.
|
||||||
|
|
||||||
|
### Consensus-Blocked Handling
|
||||||
|
|
||||||
|
When a worker reports `consensus_blocked` in its callback:
|
||||||
|
|
||||||
|
```
|
||||||
|
handleCallback receives message with consensus_blocked flag
|
||||||
|
+- Extract: divergence_severity, blocked_round, action_recommendation
|
||||||
|
+- Route by severity:
|
||||||
|
|
|
||||||
|
+- severity = HIGH
|
||||||
|
| +- Create REVISION task:
|
||||||
|
| +- Same role, same doc type, incremented suffix (e.g., DRAFT-001-R1)
|
||||||
|
| +- Description includes: divergence details + action items from discuss
|
||||||
|
| +- blockedBy: none (immediate execution)
|
||||||
|
| +- Max 1 revision per task (DRAFT-001 -> DRAFT-001-R1, no R2)
|
||||||
|
| +- If already revised once -> PAUSE, escalate to user
|
||||||
|
| +- Update session: mark task as "revised", log revision chain
|
||||||
|
|
|
||||||
|
+- severity = MEDIUM
|
||||||
|
| +- Proceed with warning: include divergence in next task's context
|
||||||
|
| +- Log action items to wisdom/issues.md
|
||||||
|
| +- Normal handleSpawnNext
|
||||||
|
|
|
||||||
|
+- severity = LOW
|
||||||
|
+- Proceed normally: treat as consensus_reached with notes
|
||||||
|
+- Normal handleSpawnNext
|
||||||
|
```
|
||||||
|
|
||||||
|
## Phase 4: Validation
|
||||||
|
|
||||||
|
| Check | Criteria |
|
||||||
|
|-------|----------|
|
||||||
|
| Session state consistent | active_workers matches TaskList in_progress tasks |
|
||||||
|
| No orphaned tasks | Every in_progress task has an active_worker entry |
|
||||||
|
| Dynamic roles valid | All task owners exist in session.roles |
|
||||||
|
| Completion detection | readySubjects=0 + inProgressSubjects=0 -> PIPELINE_COMPLETE |
|
||||||
|
| Fast-advance tracking | Detect tasks already in_progress via fast-advance, sync to active_workers |
|
||||||
|
| Fast-advance orphan check | in_progress tasks without active_worker entry -> reset to pending |
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Session file not found | Error, suggest re-run team-coordinate |
|
||||||
|
| Worker callback from unknown role | Log info, scan for other completions |
|
||||||
|
| All workers still running on resume | Report status, suggest check later |
|
||||||
|
| Pipeline stall (no ready, no running) | Check for missing tasks, report to user |
|
||||||
|
| Fast-advance conflict | Executor reconciles, no duplicate spawns |
|
||||||
|
| Fast-advance task orphaned | Reset to pending, re-spawn via handleSpawnNext |
|
||||||
|
| Dynamic role file not found | Error, cannot proceed without role definition |
|
||||||
|
| capability_gap from role | WARN only, cannot generate new roles |
|
||||||
|
| consensus_blocked HIGH | Create revision task (max 1) or pause for user |
|
||||||
|
| consensus_blocked MEDIUM | Proceed with warning, log to wisdom/issues.md |
|
||||||
202
.claude/skills/team-executor/roles/executor/role.md
Normal file
202
.claude/skills/team-executor/roles/executor/role.md
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
# Executor Role
|
||||||
|
|
||||||
|
Orchestrate the team-executor workflow: session validation, state reconciliation, worker dispatch, progress monitoring, session state. The sole built-in role -- all worker roles are loaded from the session.
|
||||||
|
|
||||||
|
## Identity
|
||||||
|
|
||||||
|
- **Name**: `executor` | **Tag**: `[executor]`
|
||||||
|
- **Responsibility**: Validate session -> Reconcile state -> Create team -> Dispatch tasks -> Monitor progress -> Report results
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
### MUST
|
||||||
|
- Validate session structure before any execution
|
||||||
|
- Reconcile session state with TaskList on startup
|
||||||
|
- Reset in_progress tasks to pending (interrupted tasks)
|
||||||
|
- Detect fast-advance orphans and reset to pending
|
||||||
|
- Spawn worker subagents in background
|
||||||
|
- Monitor progress via worker callbacks and route messages
|
||||||
|
- Maintain session state persistence (team-session.json)
|
||||||
|
- Handle capability_gap reports with warning only (cannot generate roles)
|
||||||
|
|
||||||
|
### MUST NOT
|
||||||
|
- Execute task work directly (delegate to workers)
|
||||||
|
- Modify task output artifacts (workers own their deliverables)
|
||||||
|
- Call implementation subagents (code-developer, etc.) directly
|
||||||
|
- Generate new roles (use existing session roles only)
|
||||||
|
- Skip session validation
|
||||||
|
- Override consensus_blocked HIGH without user confirmation
|
||||||
|
|
||||||
|
> **Core principle**: executor is the orchestrator, not the executor. All actual work is delegated to session-defined worker roles. Unlike team-coordinate coordinator, executor CANNOT generate new roles.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entry Router
|
||||||
|
|
||||||
|
When executor is invoked, first detect the invocation type:
|
||||||
|
|
||||||
|
| Detection | Condition | Handler |
|
||||||
|
|-----------|-----------|---------|
|
||||||
|
| Worker callback | Message contains `[role-name]` from session roles | -> handleCallback |
|
||||||
|
| Status check | Arguments contain "check" or "status" | -> handleCheck |
|
||||||
|
| Manual resume | Arguments contain "resume" or "continue" | -> handleResume |
|
||||||
|
| Capability gap | Message contains "capability_gap" | -> handleAdapt |
|
||||||
|
| New execution | None of above | -> Phase 0 |
|
||||||
|
|
||||||
|
For callback/check/resume/adapt: load `commands/monitor.md` and execute the appropriate handler, then STOP.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 0: Session Validation + State Reconciliation
|
||||||
|
|
||||||
|
**Objective**: Validate session structure and reconcile session state with actual task status.
|
||||||
|
|
||||||
|
**Workflow**:
|
||||||
|
|
||||||
|
### Step 1: Session Validation
|
||||||
|
|
||||||
|
Validate session structure (see SKILL.md Session Validation):
|
||||||
|
- [ ] Directory exists at session path
|
||||||
|
- [ ] `team-session.json` exists and parses
|
||||||
|
- [ ] `task-analysis.json` exists and parses
|
||||||
|
- [ ] `roles/` directory has >= 1 .md files
|
||||||
|
- [ ] All roles in team-session.json#roles have corresponding .md files
|
||||||
|
|
||||||
|
If validation fails -> ERROR with specific reason -> STOP
|
||||||
|
|
||||||
|
### Step 2: Load Session State
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
session = Read(<session-folder>/team-session.json)
|
||||||
|
taskAnalysis = Read(<session-folder>/task-analysis.json)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Reconcile with TaskList
|
||||||
|
|
||||||
|
```
|
||||||
|
Call TaskList() -> get real status of all tasks
|
||||||
|
Compare with session.completed_tasks:
|
||||||
|
+- Tasks in TaskList.completed but not in session -> add to session.completed_tasks
|
||||||
|
+- Tasks in session.completed_tasks but not TaskList.completed -> remove from session.completed_tasks (anomaly, log warning)
|
||||||
|
+- Tasks in TaskList.in_progress -> candidate for reset
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Reset Interrupted Tasks
|
||||||
|
|
||||||
|
```
|
||||||
|
For each task in TaskList.in_progress:
|
||||||
|
+- Reset to pending via TaskUpdate
|
||||||
|
+- Log via team_msg (type: warning, summary: "Task <ID> reset from interrupted state")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 5: Detect Fast-Advance Orphans
|
||||||
|
|
||||||
|
```
|
||||||
|
For each task in TaskList.in_progress:
|
||||||
|
+- Check if has matching active_worker entry
|
||||||
|
+- No matching active_worker + created > 5 minutes ago -> orphan
|
||||||
|
+- Reset to pending via TaskUpdate
|
||||||
|
+- Log via team_msg (type: error, summary: "Fast-advance orphan <ID> reset")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 6: Create Missing Tasks (if needed)
|
||||||
|
|
||||||
|
```
|
||||||
|
For each task in task-analysis.json#tasks:
|
||||||
|
+- Check if exists in TaskList
|
||||||
|
+- Not exists -> create via TaskCreate with correct blockedBy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 7: Update Session File
|
||||||
|
|
||||||
|
```
|
||||||
|
Write updated team-session.json with:
|
||||||
|
+- reconciled completed_tasks
|
||||||
|
+- cleared active_workers (will be rebuilt on spawn)
|
||||||
|
+- status = "active"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 8: Team Setup
|
||||||
|
|
||||||
|
```
|
||||||
|
Check if team exists (via TaskList with team_name filter)
|
||||||
|
+- Not exists -> TeamCreate with team_name from session
|
||||||
|
+- Exists -> continue with existing team
|
||||||
|
```
|
||||||
|
|
||||||
|
**Success**: Session validated, state reconciled, team ready -> Phase 1
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Spawn-and-Stop
|
||||||
|
|
||||||
|
**Objective**: Spawn first batch of ready workers in background, then STOP.
|
||||||
|
|
||||||
|
**Design**: Spawn-and-Stop + Callback pattern, with worker fast-advance.
|
||||||
|
- Spawn workers with `Task(run_in_background: true)` -> immediately return
|
||||||
|
- Worker completes -> may fast-advance to next task OR SendMessage callback -> auto-advance
|
||||||
|
- User can use "check" / "resume" to manually advance
|
||||||
|
- Executor does one operation per invocation, then STOPS
|
||||||
|
|
||||||
|
**Workflow**:
|
||||||
|
1. Load `commands/monitor.md`
|
||||||
|
2. Find tasks with: status=pending, blockedBy all resolved, owner assigned
|
||||||
|
3. For each ready task -> spawn worker (see SKILL.md Executor Spawn Template)
|
||||||
|
- Use Standard Worker template for single-task roles
|
||||||
|
- Use Inner Loop Worker template for multi-task roles
|
||||||
|
4. Output status summary with execution graph
|
||||||
|
5. STOP
|
||||||
|
|
||||||
|
**Pipeline advancement** driven by three wake sources:
|
||||||
|
- Worker callback (automatic) -> Entry Router -> handleCallback
|
||||||
|
- User "check" -> handleCheck (status only)
|
||||||
|
- User "resume" -> handleResume (advance)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Report + Next Steps
|
||||||
|
|
||||||
|
**Objective**: Completion report and follow-up options.
|
||||||
|
|
||||||
|
**Workflow**:
|
||||||
|
1. Load session state -> count completed tasks, duration
|
||||||
|
2. List all deliverables with output paths in `<session>/artifacts/`
|
||||||
|
3. Include discussion summaries (if inline discuss was used)
|
||||||
|
4. Summarize wisdom accumulated during execution
|
||||||
|
5. Update session status -> "completed"
|
||||||
|
6. Offer next steps: exit / view artifacts / extend with additional tasks
|
||||||
|
|
||||||
|
**Output format**:
|
||||||
|
|
||||||
|
```
|
||||||
|
[executor] ============================================
|
||||||
|
[executor] TASK COMPLETE
|
||||||
|
[executor]
|
||||||
|
[executor] Deliverables:
|
||||||
|
[executor] - <artifact-1.md> (<producer role>)
|
||||||
|
[executor] - <artifact-2.md> (<producer role>)
|
||||||
|
[executor]
|
||||||
|
[executor] Pipeline: <completed>/<total> tasks
|
||||||
|
[executor] Roles: <role-list>
|
||||||
|
[executor] Duration: <elapsed>
|
||||||
|
[executor]
|
||||||
|
[executor] Session: <session-folder>
|
||||||
|
[executor] ============================================
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Error | Resolution |
|
||||||
|
|-------|------------|
|
||||||
|
| Session validation fails | ERROR with specific reason, suggest re-run team-coordinate |
|
||||||
|
| Task timeout | Log, mark failed, ask user to retry or skip |
|
||||||
|
| Worker crash | Respawn worker, reassign task |
|
||||||
|
| Session corruption | Attempt recovery, fallback to manual reconciliation |
|
||||||
|
| capability_gap reported | handleAdapt: WARN only, cannot generate new roles |
|
||||||
|
| All workers still running on resume | Report status, suggest check later |
|
||||||
|
| Pipeline stall (no ready, no running) | Check for missing tasks, report to user |
|
||||||
|
| Fast-advance conflict | Executor reconciles, no duplicate spawns |
|
||||||
|
| Fast-advance task orphaned | Reset to pending, re-spawn via handleSpawnNext |
|
||||||
|
| Role file not found | ERROR, cannot proceed without role definition |
|
||||||
227
.claude/skills/team-executor/specs/session-schema.md
Normal file
227
.claude/skills/team-executor/specs/session-schema.md
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
# Session Schema
|
||||||
|
|
||||||
|
Required session structure for team-executor. All components MUST exist for valid execution.
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
<session-folder>/
|
||||||
|
+-- team-session.json # Session state + dynamic role registry (REQUIRED)
|
||||||
|
+-- task-analysis.json # Task analysis output: capabilities, dependency graph (REQUIRED)
|
||||||
|
+-- roles/ # Dynamic role definitions (REQUIRED, >= 1 .md file)
|
||||||
|
| +-- <role-1>.md
|
||||||
|
| +-- <role-2>.md
|
||||||
|
+-- artifacts/ # All MD deliverables from workers
|
||||||
|
| +-- <artifact>.md
|
||||||
|
+-- shared-memory.json # Cross-role state store
|
||||||
|
+-- wisdom/ # Cross-task knowledge
|
||||||
|
| +-- learnings.md
|
||||||
|
| +-- decisions.md
|
||||||
|
| +-- issues.md
|
||||||
|
+-- explorations/ # Shared explore cache
|
||||||
|
| +-- cache-index.json
|
||||||
|
| +-- explore-<angle>.json
|
||||||
|
+-- discussions/ # Inline discuss records
|
||||||
|
| +-- <round>.md
|
||||||
|
+-- .msg/ # Team message bus logs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Checklist
|
||||||
|
|
||||||
|
team-executor validates the following before execution:
|
||||||
|
|
||||||
|
### Required Components
|
||||||
|
|
||||||
|
| Component | Validation | Error Message |
|
||||||
|
|-----------|------------|---------------|
|
||||||
|
| `--session` argument | Must be provided | "Session required. Usage: --session=<path-to-TC-folder>" |
|
||||||
|
| Directory | Must exist at path | "Session directory not found: <path>" |
|
||||||
|
| `team-session.json` | Must exist and parse as JSON | "Invalid session: team-session.json missing or corrupt" |
|
||||||
|
| `task-analysis.json` | Must exist and parse as JSON | "Invalid session: task-analysis.json missing or corrupt" |
|
||||||
|
| `roles/` directory | Must exist and contain >= 1 .md file | "Invalid session: no role files in roles/" |
|
||||||
|
| Role file mapping | Each role in team-session.json#roles must have .md file | "Role file not found: roles/<role>.md" |
|
||||||
|
|
||||||
|
### Validation Algorithm
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Parse --session=<path> from arguments
|
||||||
|
+- Not provided -> ERROR: "Session required. Usage: --session=<path-to-TC-folder>"
|
||||||
|
|
||||||
|
2. Check directory exists
|
||||||
|
+- Not exists -> ERROR: "Session directory not found: <path>"
|
||||||
|
|
||||||
|
3. Check team-session.json
|
||||||
|
+- Not exists -> ERROR: "Invalid session: team-session.json missing"
|
||||||
|
+- Parse error -> ERROR: "Invalid session: team-session.json corrupt"
|
||||||
|
|
||||||
|
4. Check task-analysis.json
|
||||||
|
+- Not exists -> ERROR: "Invalid session: task-analysis.json missing"
|
||||||
|
+- Parse error -> ERROR: "Invalid session: task-analysis.json corrupt"
|
||||||
|
|
||||||
|
5. Check roles/ directory
|
||||||
|
+- Not exists -> ERROR: "Invalid session: roles/ directory missing"
|
||||||
|
+- No .md files -> ERROR: "Invalid session: no role files in roles/"
|
||||||
|
|
||||||
|
6. Check role file mapping
|
||||||
|
+- For each role in team-session.json#roles:
|
||||||
|
+- Check roles/<role.name>.md exists
|
||||||
|
+- Not exists -> ERROR: "Role file not found: roles/<role.name>.md"
|
||||||
|
|
||||||
|
7. All checks pass -> proceed to Phase 0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## team-session.json Schema
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"session_id": "TC-<slug>-<date>",
|
||||||
|
"task_description": "<original user input>",
|
||||||
|
"status": "active | paused | completed",
|
||||||
|
"team_name": "<team-name>",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"name": "<role-name>",
|
||||||
|
"prefix": "<PREFIX>",
|
||||||
|
"responsibility_type": "<type>",
|
||||||
|
"inner_loop": false,
|
||||||
|
"role_file": "roles/<role-name>.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pipeline": {
|
||||||
|
"dependency_graph": {},
|
||||||
|
"tasks_total": 0,
|
||||||
|
"tasks_completed": 0
|
||||||
|
},
|
||||||
|
"active_workers": [],
|
||||||
|
"completed_tasks": [],
|
||||||
|
"created_at": "<timestamp>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Required Fields
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `session_id` | string | Unique session identifier (e.g., "TC-auth-feature-2026-02-27") |
|
||||||
|
| `task_description` | string | Original task description from user |
|
||||||
|
| `status` | string | One of: "active", "paused", "completed" |
|
||||||
|
| `team_name` | string | Team name for Task tool |
|
||||||
|
| `roles` | array | List of role definitions |
|
||||||
|
| `roles[].name` | string | Role name (must match .md filename) |
|
||||||
|
| `roles[].prefix` | string | Task prefix for this role (e.g., "SPEC", "IMPL") |
|
||||||
|
| `roles[].role_file` | string | Relative path to role file |
|
||||||
|
|
||||||
|
### Optional Fields
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `pipeline` | object | Pipeline metadata |
|
||||||
|
| `active_workers` | array | Currently running workers |
|
||||||
|
| `completed_tasks` | array | List of completed task IDs |
|
||||||
|
| `created_at` | string | ISO timestamp |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## task-analysis.json Schema
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"capabilities": [
|
||||||
|
{
|
||||||
|
"name": "<capability-name>",
|
||||||
|
"description": "<description>",
|
||||||
|
"artifact_type": "<type>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependency_graph": {
|
||||||
|
"<task-id>": {
|
||||||
|
"depends_on": ["<dependency-task-id>"],
|
||||||
|
"role": "<role-name>"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"name": "<role-name>",
|
||||||
|
"prefix": "<PREFIX>",
|
||||||
|
"responsibility_type": "<type>",
|
||||||
|
"inner_loop": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"id": "<task-id>",
|
||||||
|
"subject": "<task-subject>",
|
||||||
|
"owner": "<role-name>",
|
||||||
|
"blockedBy": ["<dependency-task-id>"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"complexity_score": 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Required Fields
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `capabilities` | array | Detected capabilities |
|
||||||
|
| `dependency_graph` | object | Task dependency DAG |
|
||||||
|
| `roles` | array | Role definitions |
|
||||||
|
| `tasks` | array | Task definitions |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Role File Schema
|
||||||
|
|
||||||
|
Each role file in `roles/<role-name>.md` must follow the structure defined in `team-coordinate/specs/role-template.md`.
|
||||||
|
|
||||||
|
### Minimum Required Sections
|
||||||
|
|
||||||
|
| Section | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `# Role: <name>` | Header with role name |
|
||||||
|
| `## Identity` | Name, tag, prefix, responsibility |
|
||||||
|
| `## Boundaries` | MUST and MUST NOT rules |
|
||||||
|
| `## Execution (5-Phase)` | Phase 1-5 workflow |
|
||||||
|
|
||||||
|
### Validation
|
||||||
|
|
||||||
|
Role files are not validated for structure, only for existence. If a role file is malformed, the worker will fail at runtime.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Valid Session
|
||||||
|
|
||||||
|
```
|
||||||
|
.workflow/.team/TC-auth-feature-2026-02-27/
|
||||||
|
+-- team-session.json # Valid JSON with session metadata
|
||||||
|
+-- task-analysis.json # Valid JSON with dependency graph
|
||||||
|
+-- roles/
|
||||||
|
| +-- spec-writer.md # Role file for SPEC-* tasks
|
||||||
|
| +-- implementer.md # Role file for IMPL-* tasks
|
||||||
|
| +-- tester.md # Role file for TEST-* tasks
|
||||||
|
+-- artifacts/ # (may be empty)
|
||||||
|
+-- shared-memory.json # Valid JSON (may be {})
|
||||||
|
+-- wisdom/
|
||||||
|
| +-- learnings.md
|
||||||
|
| +-- decisions.md
|
||||||
|
| +-- issues.md
|
||||||
|
+-- explorations/
|
||||||
|
| +-- cache-index.json
|
||||||
|
+-- discussions/ # (may be empty)
|
||||||
|
+-- .msg/ # (may be empty)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recovery from Invalid Sessions
|
||||||
|
|
||||||
|
If session validation fails:
|
||||||
|
|
||||||
|
1. **Missing team-session.json**: Re-run team-coordinate with original task
|
||||||
|
2. **Missing task-analysis.json**: Re-run team-coordinate with --resume
|
||||||
|
3. **Missing role files**: Re-run team-coordinate with --resume
|
||||||
|
4. **Corrupt JSON**: Manual inspection or re-run team-coordinate
|
||||||
|
|
||||||
|
**team-executor cannot fix invalid sessions** -- it can only report errors and suggest recovery steps.
|
||||||
@@ -126,8 +126,9 @@ Every worker executes the same task discovery flow on startup:
|
|||||||
Standard reporting flow after task completion:
|
Standard reporting flow after task completion:
|
||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Parameters: operation="log", team="frontend", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Parameters: operation="log", team=**<session-id>**, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable -> `ccw team log --team frontend --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **CLI fallback**: When MCP unavailable -> `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
||||||
|
- **Note**: `team` must be session ID (e.g., `FES-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
||||||
3. **TaskUpdate**: Mark task completed
|
3. **TaskUpdate**: Mark task completed
|
||||||
4. **Loop**: Return to Phase 1 to check next task
|
4. **Loop**: Return to Phase 1 to check next task
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "frontend",
|
team: **<session-id>**, // MUST be session ID (e.g., FES-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "analyst",
|
from: "analyst",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -76,7 +76,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team frontend --from analyst --to coordinator --type <message-type> --summary \"[analyst] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from analyst --to coordinator --type <message-type> --summary \"[analyst] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "frontend",
|
team: **<session-id>**, // MUST be session ID (e.g., FES-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "architect",
|
from: "architect",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -74,7 +74,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team frontend --from architect --to coordinator --type <message-type> --summary \"[architect] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from architect --to coordinator --type <message-type> --summary \"[architect] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "frontend",
|
team: **<session-id>**, // MUST be session ID (e.g., FES-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "coordinator",
|
from: "coordinator",
|
||||||
to: <recipient>,
|
to: <recipient>,
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -72,7 +72,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team frontend --from coordinator --to <recipient> --type <message-type> --summary \"[coordinator] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from coordinator --to <recipient> --type <message-type> --summary \"[coordinator] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "frontend",
|
team: **<session-id>**, // MUST be session ID (e.g., FES-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "developer",
|
from: "developer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -74,7 +74,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team frontend --from developer --to coordinator --type <message-type> --summary \"[developer] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from developer --to coordinator --type <message-type> --summary \"[developer] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "frontend",
|
team: **<session-id>**, // MUST be session ID (e.g., FES-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "qa",
|
from: "qa",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -74,7 +74,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team frontend --from qa --to coordinator --type <message-type> --summary \"[qa] ...\" --ref <audit-file> --json")
|
Bash("ccw team log --team <session-id> --from qa --to coordinator --type <message-type> --summary \"[qa] ...\" --ref <audit-file> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -116,8 +116,9 @@ Every worker executes the same task discovery flow on startup:
|
|||||||
Standard reporting flow after task completion:
|
Standard reporting flow after task completion:
|
||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Parameters: operation="log", team="issue", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Parameters: operation="log", team=**<session-id>**, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable → `ccw team log --team issue --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **CLI fallback**: When MCP unavailable → `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
||||||
|
- **Note**: `team` must be session ID (e.g., `ISS-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
||||||
3. **TaskUpdate**: Mark task completed
|
3. **TaskUpdate**: Mark task completed
|
||||||
4. **Loop**: Return to Phase 1 to check next task
|
4. **Loop**: Return to Phase 1 to check next task
|
||||||
@@ -157,9 +158,11 @@ All outputs must carry `[role_name]` prefix in both SendMessage content/summary
|
|||||||
|
|
||||||
Every SendMessage **before**, must call `mcp__ccw-tools__team_msg` to log:
|
Every SendMessage **before**, must call `mcp__ccw-tools__team_msg` to log:
|
||||||
|
|
||||||
**Parameters**: operation="log", team="issue", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
**Parameters**: operation="log", team=**<session-id>**, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
|
|
||||||
**CLI fallback**: When MCP unavailable → `ccw team log --team issue --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
**CLI fallback**: When MCP unavailable → `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
||||||
|
|
||||||
|
**Note**: `team` must be session ID (e.g., `ISS-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**Message types by role**:
|
**Message types by role**:
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "issue",
|
team: **<session-id>**, // MUST be session ID (e.g., ISS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "coordinator",
|
from: "coordinator",
|
||||||
to: "<recipient>",
|
to: "<recipient>",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -86,7 +86,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team issue --from coordinator --to <recipient> --type <message-type> --summary \"[coordinator] ...\" --json")
|
Bash("ccw team log --team <session-id> --from coordinator --to <recipient> --type <message-type> --summary \"[coordinator] ...\" --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "issue",
|
team: **<session-id>**, // MUST be session ID (e.g., ISS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "explorer",
|
from: "explorer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -75,7 +75,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team issue --from explorer --to coordinator --type <message-type> --summary \"[explorer] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from explorer --to coordinator --type <message-type> --summary \"[explorer] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "issue",
|
team: **<session-id>**, // MUST be session ID (e.g., ISS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "implementer",
|
from: "implementer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -84,7 +84,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team issue --from implementer --to coordinator --type <message-type> --summary \"[implementer] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from implementer --to coordinator --type <message-type> --summary \"[implementer] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -264,7 +264,7 @@ Bash("<testCmd> 2>&1 || echo \"TEST_FAILED\"")
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "issue", from: "implementer", to: "coordinator",
|
operation: "log", team: **<session-id>**, from: "implementer", to: "coordinator", // MUST be session ID, NOT team name
|
||||||
type: "impl_failed",
|
type: "impl_failed",
|
||||||
summary: "[implementer] Tests failing for <issueId> after implementation (via <executor>)"
|
summary: "[implementer] Tests failing for <issueId> after implementation (via <executor>)"
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "issue",
|
team: **<session-id>**, // MUST be session ID (e.g., ISS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "integrator",
|
from: "integrator",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -74,7 +74,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team issue --from integrator --to coordinator --type <message-type> --summary \"[integrator] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from integrator --to coordinator --type <message-type> --summary \"[integrator] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -116,7 +116,7 @@ Bash("ccw issue solutions <issueId> --json")
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "issue", from: "integrator", to: "coordinator",
|
operation: "log", team: **<session-id>**, from: "integrator", to: "coordinator", // MUST be session ID, NOT team name
|
||||||
type: "error",
|
type: "error",
|
||||||
summary: "[integrator] Unbound issues: <issueIds> - cannot form queue"
|
summary: "[integrator] Unbound issues: <issueIds> - cannot form queue"
|
||||||
})
|
})
|
||||||
@@ -192,7 +192,7 @@ Read(".workflow/issues/queue/execution-queue.json")
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "issue", from: "integrator", to: "coordinator",
|
operation: "log", team: **<session-id>**, from: "integrator", to: "coordinator", // MUST be session ID, NOT team name
|
||||||
type: "conflict_found",
|
type: "conflict_found",
|
||||||
summary: "[integrator] <count> unresolved conflicts in queue"
|
summary: "[integrator] <count> unresolved conflicts in queue"
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "issue",
|
team: **<session-id>**, // MUST be session ID (e.g., ISS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "planner",
|
from: "planner",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -74,7 +74,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team issue --from planner --to coordinator --type <message-type> --summary \"[planner] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from planner --to coordinator --type <message-type> --summary \"[planner] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -159,7 +159,7 @@ Design an ALTERNATIVE approach that addresses the reviewer's concerns.
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "issue", from: "planner", to: "coordinator",
|
operation: "log", team: **<session-id>**, from: "planner", to: "coordinator", // MUST be session ID, NOT team name
|
||||||
type: "solution_ready",
|
type: "solution_ready",
|
||||||
summary: "[planner] Solution <solution_id> bound to <issue_id> (<task_count> tasks)"
|
summary: "[planner] Solution <solution_id> bound to <issue_id> (<task_count> tasks)"
|
||||||
})
|
})
|
||||||
@@ -175,7 +175,7 @@ SendMessage({
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "issue", from: "planner", to: "coordinator",
|
operation: "log", team: **<session-id>**, from: "planner", to: "coordinator", // MUST be session ID, NOT team name
|
||||||
type: "multi_solution",
|
type: "multi_solution",
|
||||||
summary: "[planner] <count> solutions for <issue_id>, user selection needed"
|
summary: "[planner] <count> solutions for <issue_id>, user selection needed"
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "issue",
|
team: **<session-id>**, // MUST be session ID (e.g., ISS-xxx-date), NOT team name. Extract from Session: field.
|
||||||
from: "reviewer",
|
from: "reviewer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -77,7 +77,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team issue --from reviewer --to coordinator --type <message-type> --summary \"[reviewer] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from reviewer --to coordinator --type <message-type> --summary \"[reviewer] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -98,8 +98,9 @@ Each worker executes the same task discovery flow on startup:
|
|||||||
Standard report flow after task completion:
|
Standard report flow after task completion:
|
||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Parameters: operation="log", team=<team-name>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Parameters: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable -> `ccw team log --team <team> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **NOTE**: `team` must be **session ID** (e.g., `TID-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 with `[<role>]` prefix)
|
2. **SendMessage**: Send result to coordinator (content and summary both with `[<role>]` prefix)
|
||||||
3. **TaskUpdate**: Mark task completed
|
3. **TaskUpdate**: Mark task completed
|
||||||
4. **Loop**: Return to Phase 1 to check next task
|
4. **Loop**: Return to Phase 1 to check next task
|
||||||
@@ -116,9 +117,11 @@ Standard report flow after task completion:
|
|||||||
|
|
||||||
### Message Bus
|
### Message Bus
|
||||||
|
|
||||||
Call `mcp__ccw-tools__team_msg` with: operation="log", team=<team-name>, from=<role>, to="coordinator", type=<type>, summary="[<role>] <summary>", ref="<file_path>"
|
Call `mcp__ccw-tools__team_msg` with: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<type>, summary="[<role>] <summary>", ref="<file_path>"
|
||||||
|
|
||||||
**CLI Fallback**: `ccw team log --team "<team-name>" --from "<role>" --to "coordinator" --type "<type>" --summary "<summary>" --json`
|
**NOTE**: `team` must be **session ID** (e.g., `TID-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
|
**CLI Fallback**: `ccw team log --team "<session-id>" --from "<role>" --to "coordinator" --type "<type>" --summary "<summary>" --json`
|
||||||
|
|
||||||
| Role | Message Types |
|
| Role | Message Types |
|
||||||
|------|---------------|
|
|------|---------------|
|
||||||
|
|||||||
@@ -53,10 +53,12 @@ Technical architect. Responsible for technical design, task decomposition, and a
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||||
|
|
||||||
|
**NOTE**: `team` must be **session ID** (e.g., `TID-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "iterdev",
|
team: <session-id>, // e.g., "TID-project-2026-02-27", NOT "iterdev"
|
||||||
from: "architect",
|
from: "architect",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -68,7 +70,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team iterdev --from architect --to coordinator --type <message-type> --summary \"[architect] DESIGN complete\" --ref <design-path> --json")
|
Bash("ccw team log --team <session-id> --from architect --to coordinator --type <message-type> --summary \"[architect] DESIGN complete\" --ref <design-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -222,7 +224,7 @@ Write(<session-folder>/shared-memory.json, JSON.stringify(sharedMemory, null, 2)
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "iterdev", from: "architect", to: "coordinator",
|
operation: "log", team: <session-id>, from: "architect", to: "coordinator", // team = session ID, e.g., "TID-project-2026-02-27"
|
||||||
type: "design_ready",
|
type: "design_ready",
|
||||||
summary: "[architect] Design complete: <count> components, <task-count> tasks",
|
summary: "[architect] Design complete: <count> components, <task-count> tasks",
|
||||||
ref: <design-path>
|
ref: <design-path>
|
||||||
|
|||||||
@@ -381,10 +381,12 @@ Identifies, tracks, and prioritizes technical debt.
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||||
|
|
||||||
|
**NOTE**: `team` must be **session ID** (e.g., `TID-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "iterdev",
|
team: <session-id>, // e.g., "TID-project-2026-02-27", NOT "iterdev"
|
||||||
from: "coordinator",
|
from: "coordinator",
|
||||||
to: "all",
|
to: "all",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -396,7 +398,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team iterdev --from coordinator --to all --type <message-type> --summary \"[coordinator] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from coordinator --to all --type <message-type> --summary \"[coordinator] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -56,10 +56,12 @@ Code implementer. Responsible for implementing code according to design, increme
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||||
|
|
||||||
|
**NOTE**: `team` must be **session ID** (e.g., `TID-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "iterdev",
|
team: <session-id>, // e.g., "TID-project-2026-02-27", NOT "iterdev"
|
||||||
from: "developer",
|
from: "developer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -71,7 +73,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team iterdev --from developer --to coordinator --type <message-type> --summary \"[developer] DEV complete\" --ref <dev-log-path> --json")
|
Bash("ccw team log --team <session-id> --from developer --to coordinator --type <message-type> --summary \"[developer] DEV complete\" --ref <dev-log-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -232,7 +234,7 @@ Write(<session-folder>/shared-memory.json, JSON.stringify(sharedMemory, null, 2)
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "iterdev", from: "developer", to: "coordinator",
|
operation: "log", team: <session-id>, from: "developer", to: "coordinator", // team = session ID, e.g., "TID-project-2026-02-27"
|
||||||
type: "dev_complete",
|
type: "dev_complete",
|
||||||
summary: "[developer] <Fix|Implementation> complete: <file-count> files changed",
|
summary: "[developer] <Fix|Implementation> complete: <file-count> files changed",
|
||||||
ref: <dev-log-path>
|
ref: <dev-log-path>
|
||||||
|
|||||||
@@ -55,10 +55,12 @@ Code reviewer. Responsible for multi-dimensional review, quality scoring, and im
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||||
|
|
||||||
|
**NOTE**: `team` must be **session ID** (e.g., `TID-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "iterdev",
|
team: <session-id>, // e.g., "TID-project-2026-02-27", NOT "iterdev"
|
||||||
from: "reviewer",
|
from: "reviewer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -70,7 +72,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team iterdev --from reviewer --to coordinator --type <message-type> --summary \"[reviewer] REVIEW complete\" --ref <review-path> --json")
|
Bash("ccw team log --team <session-id> --from reviewer --to coordinator --type <message-type> --summary \"[reviewer] REVIEW complete\" --ref <review-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -258,7 +260,7 @@ Write(<session-folder>/shared-memory.json, JSON.stringify(sharedMemory, null, 2)
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "iterdev", from: "reviewer", to: "coordinator",
|
operation: "log", team: <session-id>, from: "reviewer", to: "coordinator", // team = session ID, e.g., "TID-project-2026-02-27"
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
summary: "[reviewer] Review <message-type>: score=<score>/10, <critical-count>C/<high-count>H",
|
summary: "[reviewer] Review <message-type>: score=<score>/10, <critical-count>C/<high-count>H",
|
||||||
ref: <review-path>
|
ref: <review-path>
|
||||||
|
|||||||
@@ -54,10 +54,12 @@ Test validator. Responsible for test execution, fix cycles, and regression detec
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||||
|
|
||||||
|
**NOTE**: `team` must be **session ID** (e.g., `TID-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "iterdev",
|
team: <session-id>, // e.g., "TID-project-2026-02-27", NOT "iterdev"
|
||||||
from: "tester",
|
from: "tester",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -69,7 +71,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team iterdev --from tester --to coordinator --type <message-type> --summary \"[tester] VERIFY complete\" --ref <verify-path> --json")
|
Bash("ccw team log --team <session-id> --from tester --to coordinator --type <message-type> --summary \"[tester] VERIFY complete\" --ref <verify-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -210,7 +212,7 @@ Write(<session-folder>/shared-memory.json, JSON.stringify(sharedMemory, null, 2)
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "iterdev", from: "tester", to: "coordinator",
|
operation: "log", team: <session-id>, from: "tester", to: "coordinator", // team = session ID, e.g., "TID-project-2026-02-27"
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
summary: "[tester] <message-type>: pass_rate=<rate>%, iterations=<count>",
|
summary: "[tester] <message-type>: pass_rate=<rate>%, iterations=<count>",
|
||||||
ref: <verify-path>
|
ref: <verify-path>
|
||||||
|
|||||||
@@ -113,8 +113,9 @@ When invoked without `--role`, coordinator auto-starts. User just provides task
|
|||||||
任务完成后的标准报告流程:
|
任务完成后的标准报告流程:
|
||||||
|
|
||||||
1. **Message Bus**: 调用 `mcp__ccw-tools__team_msg` 记录消息
|
1. **Message Bus**: 调用 `mcp__ccw-tools__team_msg` 记录消息
|
||||||
- 参数: operation="log", team=<team-name>, from=<role>, to="coordinator", type=<消息类型>, summary="[<role>] <摘要>", ref=<产物路径>
|
- 参数: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<消息类型>, summary="[<role>] <摘要>", ref=<产物路径>
|
||||||
- **CLI fallback**: 当 MCP 不可用时 → `ccw team log --team <team> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **注意**: `team` 必须是 **session ID** (如 `TLS-project-2026-02-27`), 不是 team name. 从任务描述的 `Session:` 字段提取.
|
||||||
|
- **CLI fallback**: 当 MCP 不可用时 → `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
||||||
2. **SendMessage**: 发送结果给 coordinator (content 和 summary 都带 `[<role>]` 前缀)
|
2. **SendMessage**: 发送结果给 coordinator (content 和 summary 都带 `[<role>]` 前缀)
|
||||||
3. **TaskUpdate**: 标记任务 completed
|
3. **TaskUpdate**: 标记任务 completed
|
||||||
4. **Loop**: 回到 Phase 1 检查下一个任务
|
4. **Loop**: 回到 Phase 1 检查下一个任务
|
||||||
|
|||||||
93
.claude/skills/team-lifecycle-v5/role-specs/analyst.md
Normal file
93
.claude/skills/team-lifecycle-v5/role-specs/analyst.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
role: analyst
|
||||||
|
prefix: RESEARCH
|
||||||
|
inner_loop: false
|
||||||
|
discuss_rounds: [DISCUSS-001]
|
||||||
|
subagents: [explore, discuss]
|
||||||
|
message_types:
|
||||||
|
success: research_ready
|
||||||
|
progress: research_progress
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# Analyst — Phase 2-4
|
||||||
|
|
||||||
|
## Phase 2: Seed Analysis
|
||||||
|
|
||||||
|
**Objective**: Extract structured seed information from the topic/idea.
|
||||||
|
|
||||||
|
1. Extract session folder from task description (`Session: <path>`)
|
||||||
|
2. Parse topic from task description (first non-metadata line)
|
||||||
|
3. If topic starts with `@` or ends with `.md`/`.txt` → Read the referenced file as topic content
|
||||||
|
4. Run Gemini CLI seed analysis:
|
||||||
|
|
||||||
|
```
|
||||||
|
Bash({
|
||||||
|
command: `ccw cli -p "PURPOSE: Analyze topic and extract structured seed information.
|
||||||
|
TASK: * Extract problem statement * Identify target users * Determine domain context
|
||||||
|
* List constraints and assumptions * Identify 3-5 exploration dimensions * Assess complexity
|
||||||
|
TOPIC: <topic-content>
|
||||||
|
MODE: analysis
|
||||||
|
EXPECTED: JSON with: problem_statement, target_users[], domain, constraints[], exploration_dimensions[], complexity_assessment" --tool gemini --mode analysis`,
|
||||||
|
run_in_background: true
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Wait for CLI result, parse seed analysis JSON
|
||||||
|
|
||||||
|
## Phase 3: Codebase Exploration (conditional)
|
||||||
|
|
||||||
|
**Objective**: Gather codebase context if an existing project is detected.
|
||||||
|
|
||||||
|
| Condition | Action |
|
||||||
|
|-----------|--------|
|
||||||
|
| package.json / Cargo.toml / pyproject.toml / go.mod exists | Explore codebase |
|
||||||
|
| No project files | Skip → codebase context = null |
|
||||||
|
|
||||||
|
**When project detected**: Call explore subagent with `angle: general`, `keywords: <from seed analysis>`.
|
||||||
|
|
||||||
|
```
|
||||||
|
Task({
|
||||||
|
subagent_type: "cli-explore-agent",
|
||||||
|
run_in_background: false,
|
||||||
|
description: "Explore general context",
|
||||||
|
prompt: "Explore codebase for: <topic>\nFocus angle: general\nKeywords: <seed analysis keywords>\nSession folder: <session-folder>\n..."
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Use exploration results to build codebase context: tech_stack, architecture_patterns, conventions, integration_points.
|
||||||
|
|
||||||
|
## Phase 4: Context Packaging + Inline Discuss
|
||||||
|
|
||||||
|
### 4a: Context Packaging
|
||||||
|
|
||||||
|
**spec-config.json** → `<session-folder>/spec/spec-config.json`:
|
||||||
|
- session_id, topic, status="research_complete", complexity, depth, focus_areas, mode="interactive"
|
||||||
|
|
||||||
|
**discovery-context.json** → `<session-folder>/spec/discovery-context.json`:
|
||||||
|
- session_id, phase=1, seed_analysis (all fields), codebase_context (or null), recommendations
|
||||||
|
|
||||||
|
**design-intelligence.json** → `<session-folder>/analysis/design-intelligence.json` (UI mode only):
|
||||||
|
- Produced when frontend keywords detected in seed_analysis
|
||||||
|
- Fields: industry, style_direction, ux_patterns, color_strategy, typography, component_patterns
|
||||||
|
|
||||||
|
### 4b: Inline Discuss (DISCUSS-001)
|
||||||
|
|
||||||
|
Call discuss subagent with:
|
||||||
|
- Artifact: `<session-folder>/spec/discovery-context.json`
|
||||||
|
- Round: DISCUSS-001
|
||||||
|
- Perspectives: product, risk, coverage
|
||||||
|
|
||||||
|
Handle discuss verdict per team-worker consensus handling protocol.
|
||||||
|
|
||||||
|
**Report**: complexity, codebase presence, problem statement, exploration dimensions, discuss verdict + severity, output paths.
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Gemini CLI failure | Fallback to direct Claude analysis |
|
||||||
|
| Codebase detection failed | Continue as new project |
|
||||||
|
| Topic too vague | Report with clarification questions |
|
||||||
|
| Explore subagent fails | Continue without codebase context |
|
||||||
|
| Discuss subagent fails | Proceed without discuss, log warning |
|
||||||
76
.claude/skills/team-lifecycle-v5/role-specs/architect.md
Normal file
76
.claude/skills/team-lifecycle-v5/role-specs/architect.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
role: architect
|
||||||
|
prefix: ARCH
|
||||||
|
inner_loop: false
|
||||||
|
discuss_rounds: []
|
||||||
|
subagents: [explore]
|
||||||
|
message_types:
|
||||||
|
success: arch_ready
|
||||||
|
concern: arch_concern
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# Architect — Phase 2-4
|
||||||
|
|
||||||
|
## Consultation Modes
|
||||||
|
|
||||||
|
| Task Pattern | Mode | Focus |
|
||||||
|
|-------------|------|-------|
|
||||||
|
| ARCH-SPEC-* | spec-review | Review architecture docs |
|
||||||
|
| ARCH-PLAN-* | plan-review | Review plan soundness |
|
||||||
|
| ARCH-CODE-* | code-review | Assess code change impact |
|
||||||
|
| ARCH-CONSULT-* | consult | Answer architecture questions |
|
||||||
|
| ARCH-FEASIBILITY-* | feasibility | Technical feasibility |
|
||||||
|
|
||||||
|
## Phase 2: Context Loading
|
||||||
|
|
||||||
|
**Common**: session folder, wisdom, project-tech.json, explorations
|
||||||
|
|
||||||
|
**Mode-specific**:
|
||||||
|
|
||||||
|
| Mode | Additional Context |
|
||||||
|
|------|-------------------|
|
||||||
|
| spec-review | architecture/_index.md, ADR-*.md |
|
||||||
|
| plan-review | plan/plan.json |
|
||||||
|
| code-review | git diff, changed files |
|
||||||
|
| consult | Question from task description |
|
||||||
|
| feasibility | Requirements + codebase |
|
||||||
|
|
||||||
|
## Phase 3: Assessment
|
||||||
|
|
||||||
|
Analyze using mode-specific criteria. Output: mode, verdict (APPROVE/CONCERN/BLOCK), dimensions[], concerns[], recommendations[].
|
||||||
|
|
||||||
|
For complex questions → Gemini CLI with architecture review rule:
|
||||||
|
|
||||||
|
```
|
||||||
|
Bash({
|
||||||
|
command: `ccw cli -p "..." --tool gemini --mode analysis --rule analysis-review-architecture`,
|
||||||
|
run_in_background: true
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Phase 4: Report
|
||||||
|
|
||||||
|
Output to `<session-folder>/architecture/arch-<slug>.json`. Contribute decisions to wisdom/decisions.md.
|
||||||
|
|
||||||
|
**Frontend project outputs** (when frontend tech stack detected):
|
||||||
|
- `<session-folder>/architecture/design-tokens.json` — color, spacing, typography, shadow tokens
|
||||||
|
- `<session-folder>/architecture/component-specs/*.md` — per-component design spec
|
||||||
|
|
||||||
|
**Report**: mode, verdict, concern count, recommendations, output path(s).
|
||||||
|
|
||||||
|
### Coordinator Integration
|
||||||
|
|
||||||
|
| Timing | Task |
|
||||||
|
|--------|------|
|
||||||
|
| After DRAFT-003 | ARCH-SPEC-001: architecture doc review |
|
||||||
|
| After PLAN-001 | ARCH-PLAN-001: plan architecture review |
|
||||||
|
| On-demand | ARCH-CONSULT-001: architecture consultation |
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Docs not found | Assess from available context |
|
||||||
|
| CLI timeout | Partial assessment |
|
||||||
|
| Insufficient context | Request explorer via coordinator |
|
||||||
67
.claude/skills/team-lifecycle-v5/role-specs/executor.md
Normal file
67
.claude/skills/team-lifecycle-v5/role-specs/executor.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
role: executor
|
||||||
|
prefix: IMPL
|
||||||
|
inner_loop: true
|
||||||
|
discuss_rounds: []
|
||||||
|
subagents: []
|
||||||
|
message_types:
|
||||||
|
success: impl_complete
|
||||||
|
progress: impl_progress
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# Executor — Phase 2-4
|
||||||
|
|
||||||
|
## Phase 2: Task & Plan Loading
|
||||||
|
|
||||||
|
**Objective**: Load plan and determine execution strategy.
|
||||||
|
|
||||||
|
1. Load plan.json and .task/TASK-*.json from `<session-folder>/plan/`
|
||||||
|
|
||||||
|
**Backend selection** (priority order):
|
||||||
|
|
||||||
|
| Priority | Source | Method |
|
||||||
|
|----------|--------|--------|
|
||||||
|
| 1 | Task metadata | task.metadata.executor field |
|
||||||
|
| 2 | Plan default | "Execution Backend:" in plan |
|
||||||
|
| 3 | Auto-select | Simple (< 200 chars, no refactor) → agent; Complex → codex |
|
||||||
|
|
||||||
|
**Code review selection**:
|
||||||
|
|
||||||
|
| Priority | Source | Method |
|
||||||
|
|----------|--------|--------|
|
||||||
|
| 1 | Task metadata | task.metadata.code_review field |
|
||||||
|
| 2 | Plan default | "Code Review:" in plan |
|
||||||
|
| 3 | Auto-select | Critical keywords (auth, security, payment) → enabled |
|
||||||
|
|
||||||
|
## Phase 3: Code Implementation
|
||||||
|
|
||||||
|
**Objective**: Execute implementation across batches.
|
||||||
|
|
||||||
|
**Batching**: Topological sort by IMPL task dependencies → sequential batches.
|
||||||
|
|
||||||
|
| Backend | Invocation | Use Case |
|
||||||
|
|---------|-----------|----------|
|
||||||
|
| agent | `Task({ subagent_type: "code-developer", run_in_background: false })` | Simple, direct edits |
|
||||||
|
| codex | `ccw cli --tool codex --mode write` (background) | Complex, architecture |
|
||||||
|
| gemini | `ccw cli --tool gemini --mode write` (background) | Analysis-heavy |
|
||||||
|
|
||||||
|
## Phase 4: Self-Validation
|
||||||
|
|
||||||
|
| Step | Method | Pass Criteria |
|
||||||
|
|------|--------|--------------|
|
||||||
|
| Syntax check | `tsc --noEmit` (30s) | Exit code 0 |
|
||||||
|
| Acceptance criteria | Match criteria keywords vs implementation | All addressed |
|
||||||
|
| Test detection | Find .test.ts/.spec.ts for modified files | Tests identified |
|
||||||
|
| Code review (optional) | gemini analysis or codex review | No blocking issues |
|
||||||
|
|
||||||
|
**Report**: task ID, status, files modified, validation results, backend used.
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Syntax errors | Retry with error context (max 3) |
|
||||||
|
| Missing dependencies | Request from coordinator |
|
||||||
|
| Backend unavailable | Fallback to agent |
|
||||||
|
| Circular dependencies | Abort, report graph |
|
||||||
79
.claude/skills/team-lifecycle-v5/role-specs/fe-developer.md
Normal file
79
.claude/skills/team-lifecycle-v5/role-specs/fe-developer.md
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
role: fe-developer
|
||||||
|
prefix: DEV-FE
|
||||||
|
inner_loop: false
|
||||||
|
discuss_rounds: []
|
||||||
|
subagents: []
|
||||||
|
message_types:
|
||||||
|
success: dev_fe_complete
|
||||||
|
progress: dev_fe_progress
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# FE Developer — Phase 2-4
|
||||||
|
|
||||||
|
## Phase 2: Context Loading
|
||||||
|
|
||||||
|
**Inputs to load**:
|
||||||
|
- Plan: `<session-folder>/plan/plan.json`
|
||||||
|
- Design tokens: `<session-folder>/architecture/design-tokens.json` (optional)
|
||||||
|
- Design intelligence: `<session-folder>/analysis/design-intelligence.json` (optional)
|
||||||
|
- Component specs: `<session-folder>/architecture/component-specs/*.md` (optional)
|
||||||
|
- Shared memory, wisdom
|
||||||
|
|
||||||
|
**Tech stack detection**:
|
||||||
|
|
||||||
|
| Signal | Framework | Styling |
|
||||||
|
|--------|-----------|---------|
|
||||||
|
| react/react-dom in deps | react | - |
|
||||||
|
| vue in deps | vue | - |
|
||||||
|
| next in deps | nextjs | - |
|
||||||
|
| tailwindcss in deps | - | tailwind |
|
||||||
|
| @shadcn/ui in deps | - | shadcn |
|
||||||
|
|
||||||
|
## Phase 3: Frontend Implementation
|
||||||
|
|
||||||
|
**Step 1**: Generate design token CSS (if tokens available)
|
||||||
|
- Convert design-tokens.json → CSS custom properties (`:root { --color-*, --space-*, --text-* }`)
|
||||||
|
- Include dark mode overrides via `@media (prefers-color-scheme: dark)`
|
||||||
|
- Write to `src/styles/tokens.css`
|
||||||
|
|
||||||
|
**Step 2**: Implement components
|
||||||
|
|
||||||
|
| Task Size | Strategy |
|
||||||
|
|-----------|----------|
|
||||||
|
| Simple (<= 3 files, single component) | `Task({ subagent_type: "code-developer", run_in_background: false })` |
|
||||||
|
| Complex (system, multi-component) | `ccw cli --tool gemini --mode write` (background) |
|
||||||
|
|
||||||
|
**Coding standards** (include in agent/CLI prompt):
|
||||||
|
- Use design token CSS variables, never hardcode colors/spacing
|
||||||
|
- Interactive elements: cursor: pointer
|
||||||
|
- Transitions: 150-300ms
|
||||||
|
- Text contrast: minimum 4.5:1
|
||||||
|
- Include focus-visible styles
|
||||||
|
- Support prefers-reduced-motion
|
||||||
|
- Responsive: mobile-first
|
||||||
|
- No emoji as functional icons
|
||||||
|
|
||||||
|
## Phase 4: Self-Validation
|
||||||
|
|
||||||
|
| Check | What |
|
||||||
|
|-------|------|
|
||||||
|
| hardcoded-color | No #hex outside tokens.css |
|
||||||
|
| cursor-pointer | Interactive elements have cursor: pointer |
|
||||||
|
| focus-styles | Interactive elements have focus styles |
|
||||||
|
| responsive | Has responsive breakpoints |
|
||||||
|
| reduced-motion | Animations respect prefers-reduced-motion |
|
||||||
|
| emoji-icon | No emoji as functional icons |
|
||||||
|
|
||||||
|
Contribute to wisdom/conventions.md. Update shared-memory.json with component inventory.
|
||||||
|
|
||||||
|
**Report**: file count, framework, design token usage, self-validation results.
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Design tokens not found | Use project defaults |
|
||||||
|
| Tech stack undetected | Default HTML + CSS |
|
||||||
|
| Subagent failure | Fallback to CLI write mode |
|
||||||
79
.claude/skills/team-lifecycle-v5/role-specs/fe-qa.md
Normal file
79
.claude/skills/team-lifecycle-v5/role-specs/fe-qa.md
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
role: fe-qa
|
||||||
|
prefix: QA-FE
|
||||||
|
inner_loop: false
|
||||||
|
discuss_rounds: []
|
||||||
|
subagents: []
|
||||||
|
message_types:
|
||||||
|
success: qa_fe_passed
|
||||||
|
result: qa_fe_result
|
||||||
|
fix: fix_required
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# FE QA — Phase 2-4
|
||||||
|
|
||||||
|
## Review Dimensions
|
||||||
|
|
||||||
|
| Dimension | Weight | Focus |
|
||||||
|
|-----------|--------|-------|
|
||||||
|
| Code Quality | 25% | TypeScript types, component structure, error handling |
|
||||||
|
| Accessibility | 25% | Semantic HTML, ARIA, keyboard nav, contrast, focus-visible |
|
||||||
|
| Design Compliance | 20% | Token usage, no hardcoded colors, no emoji icons |
|
||||||
|
| UX Best Practices | 15% | Loading/error/empty states, cursor-pointer, responsive |
|
||||||
|
| Pre-Delivery | 15% | No console.log, dark mode, i18n readiness |
|
||||||
|
|
||||||
|
## Phase 2: Context Loading
|
||||||
|
|
||||||
|
**Inputs**: design tokens, design intelligence, shared memory, previous QA results (for GC round tracking), changed frontend files via git diff.
|
||||||
|
|
||||||
|
Determine GC round from previous QA results count. Max 2 rounds.
|
||||||
|
|
||||||
|
## Phase 3: 5-Dimension Review
|
||||||
|
|
||||||
|
For each changed frontend file, check against all 5 dimensions. Score each dimension 0-10, deducting for issues found.
|
||||||
|
|
||||||
|
**Scoring deductions**:
|
||||||
|
|
||||||
|
| Severity | Deduction |
|
||||||
|
|----------|-----------|
|
||||||
|
| High | -2 to -3 |
|
||||||
|
| Medium | -1 to -1.5 |
|
||||||
|
| Low | -0.5 |
|
||||||
|
|
||||||
|
**Overall score** = weighted sum of dimension scores.
|
||||||
|
|
||||||
|
**Verdict routing**:
|
||||||
|
|
||||||
|
| Condition | Verdict |
|
||||||
|
|-----------|---------|
|
||||||
|
| Score >= 8 AND no critical issues | PASS |
|
||||||
|
| GC round >= max AND score >= 6 | PASS_WITH_WARNINGS |
|
||||||
|
| GC round >= max AND score < 6 | FAIL |
|
||||||
|
| Otherwise | NEEDS_FIX |
|
||||||
|
|
||||||
|
## Phase 4: Report
|
||||||
|
|
||||||
|
Write audit to `<session-folder>/qa/audit-fe-<task>-r<round>.json`. Update wisdom and shared memory.
|
||||||
|
|
||||||
|
**Report**: round, verdict, overall score, dimension scores, critical issues with Do/Don't format, action required (if NEEDS_FIX).
|
||||||
|
|
||||||
|
### Generator-Critic Loop
|
||||||
|
|
||||||
|
Orchestrated by coordinator:
|
||||||
|
```
|
||||||
|
Round 1: DEV-FE-001 → QA-FE-001
|
||||||
|
if NEEDS_FIX → coordinator creates DEV-FE-002 + QA-FE-002
|
||||||
|
Round 2: DEV-FE-002 → QA-FE-002
|
||||||
|
if still NEEDS_FIX → PASS_WITH_WARNINGS or FAIL (max 2)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Convergence**: score >= 8 AND critical_count = 0
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| No changed files | Report empty, score N/A |
|
||||||
|
| Design tokens not found | Skip design compliance, adjust weights |
|
||||||
|
| Max GC rounds exceeded | Force verdict |
|
||||||
98
.claude/skills/team-lifecycle-v5/role-specs/planner.md
Normal file
98
.claude/skills/team-lifecycle-v5/role-specs/planner.md
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
---
|
||||||
|
role: planner
|
||||||
|
prefix: PLAN
|
||||||
|
inner_loop: true
|
||||||
|
discuss_rounds: []
|
||||||
|
subagents: [explore]
|
||||||
|
message_types:
|
||||||
|
success: plan_ready
|
||||||
|
revision: plan_revision
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# Planner — Phase 2-4
|
||||||
|
|
||||||
|
## Phase 1.5: Load Spec Context (Full-Lifecycle)
|
||||||
|
|
||||||
|
If `<session-folder>/spec/` exists → load requirements/_index.md, architecture/_index.md, epics/_index.md, spec-config.json. Otherwise → impl-only mode.
|
||||||
|
|
||||||
|
**Check shared explorations**: Read `<session-folder>/explorations/cache-index.json` to see if analyst already cached useful explorations. Reuse rather than re-explore.
|
||||||
|
|
||||||
|
## Phase 2: Multi-Angle Exploration
|
||||||
|
|
||||||
|
**Objective**: Explore codebase to inform planning.
|
||||||
|
|
||||||
|
**Complexity routing**:
|
||||||
|
|
||||||
|
| Complexity | Criteria | Strategy |
|
||||||
|
|------------|----------|----------|
|
||||||
|
| Low | < 200 chars, no refactor/architecture keywords | ACE semantic search only |
|
||||||
|
| Medium | 200-500 chars or moderate scope | 2-3 angle explore subagent |
|
||||||
|
| High | > 500 chars, refactor/architecture, multi-module | 3-5 angle explore subagent |
|
||||||
|
|
||||||
|
For each angle, call explore subagent (cache-aware — check cache-index.json before each call):
|
||||||
|
|
||||||
|
```
|
||||||
|
Task({
|
||||||
|
subagent_type: "cli-explore-agent",
|
||||||
|
run_in_background: false,
|
||||||
|
description: "Explore <angle>",
|
||||||
|
prompt: "Explore codebase for: <task>\nFocus angle: <angle>\nKeywords: <keywords>\nSession folder: <session-folder>\n..."
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Phase 3: Plan Generation
|
||||||
|
|
||||||
|
**Objective**: Generate structured implementation plan.
|
||||||
|
|
||||||
|
| Complexity | Strategy |
|
||||||
|
|------------|----------|
|
||||||
|
| Low | Direct planning → single TASK-001 with plan.json |
|
||||||
|
| Medium/High | cli-lite-planning-agent with exploration results |
|
||||||
|
|
||||||
|
**Agent call** (Medium/High):
|
||||||
|
|
||||||
|
```
|
||||||
|
Task({
|
||||||
|
subagent_type: "cli-lite-planning-agent",
|
||||||
|
run_in_background: false,
|
||||||
|
description: "Generate implementation plan",
|
||||||
|
prompt: "Generate plan.
|
||||||
|
Output: <plan-dir>/plan.json + <plan-dir>/.task/TASK-*.json
|
||||||
|
Schema: cat ~/.ccw/workflows/cli-templates/schemas/plan-overview-base-schema.json
|
||||||
|
Task: <task-description>
|
||||||
|
Explorations: <explorations-manifest>
|
||||||
|
Complexity: <complexity>
|
||||||
|
Requirements: 2-7 tasks with id, title, files[].change, convergence.criteria, depends_on"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**Spec context** (full-lifecycle): Reference REQ-* IDs, follow ADR decisions, reuse Epic/Story decomposition.
|
||||||
|
|
||||||
|
## Phase 4: Submit for Approval
|
||||||
|
|
||||||
|
1. Read plan.json and TASK-*.json
|
||||||
|
2. Report to coordinator: complexity, task count, task list, approach, plan location
|
||||||
|
3. Wait for response: approved → complete; revision → update and resubmit
|
||||||
|
|
||||||
|
**Session files**:
|
||||||
|
```
|
||||||
|
<session-folder>/explorations/ (shared cache)
|
||||||
|
+-- cache-index.json
|
||||||
|
+-- explore-<angle>.json
|
||||||
|
|
||||||
|
<session-folder>/plan/
|
||||||
|
+-- explorations-manifest.json
|
||||||
|
+-- plan.json
|
||||||
|
+-- .task/TASK-*.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Exploration agent failure | Plan from description only |
|
||||||
|
| Planning agent failure | Fallback to direct planning |
|
||||||
|
| Plan rejected 3+ times | Notify coordinator, suggest alternative |
|
||||||
|
| Schema not found | Use basic structure |
|
||||||
|
| Cache index corrupt | Clear cache, re-explore all angles |
|
||||||
94
.claude/skills/team-lifecycle-v5/role-specs/reviewer.md
Normal file
94
.claude/skills/team-lifecycle-v5/role-specs/reviewer.md
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
role: reviewer
|
||||||
|
prefix: REVIEW
|
||||||
|
additional_prefixes: [QUALITY, IMPROVE]
|
||||||
|
inner_loop: false
|
||||||
|
discuss_rounds: [DISCUSS-006]
|
||||||
|
subagents: [discuss]
|
||||||
|
message_types:
|
||||||
|
success_review: review_result
|
||||||
|
success_quality: quality_result
|
||||||
|
fix: fix_required
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# Reviewer — Phase 2-4
|
||||||
|
|
||||||
|
## Phase 2: Mode Detection
|
||||||
|
|
||||||
|
| Task Prefix | Mode | Dimensions | Inline Discuss |
|
||||||
|
|-------------|------|-----------|---------------|
|
||||||
|
| REVIEW-* | Code Review | quality, security, architecture, requirements | None |
|
||||||
|
| QUALITY-* | Spec Quality | completeness, consistency, traceability, depth, coverage | DISCUSS-006 |
|
||||||
|
| IMPROVE-* | Spec Quality (recheck) | Same as QUALITY | DISCUSS-006 |
|
||||||
|
|
||||||
|
## Phase 3: Review Execution
|
||||||
|
|
||||||
|
### Code Review (REVIEW-*)
|
||||||
|
|
||||||
|
**Inputs**: Plan file, git diff, modified files, test results (if available)
|
||||||
|
|
||||||
|
**4 dimensions**:
|
||||||
|
|
||||||
|
| Dimension | Critical Issues |
|
||||||
|
|-----------|----------------|
|
||||||
|
| Quality | Empty catch, any in public APIs, @ts-ignore, console.log |
|
||||||
|
| Security | Hardcoded secrets, SQL injection, eval/exec, innerHTML |
|
||||||
|
| Architecture | Circular deps, parent imports >2 levels, files >500 lines |
|
||||||
|
| Requirements | Missing core functionality, incomplete acceptance criteria |
|
||||||
|
|
||||||
|
### Spec Quality (QUALITY-* / IMPROVE-*)
|
||||||
|
|
||||||
|
**Inputs**: All spec docs in session folder, quality gate config
|
||||||
|
|
||||||
|
**5 dimensions**:
|
||||||
|
|
||||||
|
| Dimension | Weight | Focus |
|
||||||
|
|-----------|--------|-------|
|
||||||
|
| Completeness | 25% | All sections present with substance |
|
||||||
|
| Consistency | 20% | Terminology, format, references |
|
||||||
|
| Traceability | 25% | Goals -> Reqs -> Arch -> Stories chain |
|
||||||
|
| Depth | 20% | AC testable, ADRs justified, stories estimable |
|
||||||
|
| Coverage | 10% | Original requirements mapped |
|
||||||
|
|
||||||
|
**Quality gate**:
|
||||||
|
|
||||||
|
| Gate | Criteria |
|
||||||
|
|------|----------|
|
||||||
|
| PASS | Score >= 80% AND coverage >= 70% |
|
||||||
|
| REVIEW | Score 60-79% OR coverage 50-69% |
|
||||||
|
| FAIL | Score < 60% OR coverage < 50% |
|
||||||
|
|
||||||
|
**Artifacts**: readiness-report.md + spec-summary.md
|
||||||
|
|
||||||
|
## Phase 4: Verdict + Inline Discuss
|
||||||
|
|
||||||
|
### Code Review Verdict
|
||||||
|
|
||||||
|
| Verdict | Criteria |
|
||||||
|
|---------|----------|
|
||||||
|
| BLOCK | Critical issues present |
|
||||||
|
| CONDITIONAL | High/medium only |
|
||||||
|
| APPROVE | Low or none |
|
||||||
|
|
||||||
|
### Spec Quality Inline Discuss (DISCUSS-006)
|
||||||
|
|
||||||
|
After generating readiness-report.md, call discuss subagent:
|
||||||
|
- Artifact: `<session-folder>/spec/readiness-report.md`
|
||||||
|
- Round: DISCUSS-006
|
||||||
|
- Perspectives: product, technical, quality, risk, coverage (all 5)
|
||||||
|
|
||||||
|
Handle discuss verdict per team-worker consensus handling protocol.
|
||||||
|
|
||||||
|
> **Note**: DISCUSS-006 HIGH always triggers user pause (final sign-off gate), regardless of revision count.
|
||||||
|
|
||||||
|
**Report**: mode, verdict/gate, dimension scores, discuss verdict (QUALITY only), output paths.
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Missing context | Request from coordinator |
|
||||||
|
| Invalid mode | Abort with error |
|
||||||
|
| Analysis failure | Retry, then fallback template |
|
||||||
|
| Discuss subagent fails | Proceed without final discuss, log warning |
|
||||||
76
.claude/skills/team-lifecycle-v5/role-specs/tester.md
Normal file
76
.claude/skills/team-lifecycle-v5/role-specs/tester.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
role: tester
|
||||||
|
prefix: TEST
|
||||||
|
inner_loop: false
|
||||||
|
discuss_rounds: []
|
||||||
|
subagents: []
|
||||||
|
message_types:
|
||||||
|
success: test_result
|
||||||
|
fix: fix_required
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tester — Phase 2-4
|
||||||
|
|
||||||
|
## Phase 2: Framework Detection & Test Discovery
|
||||||
|
|
||||||
|
**Framework detection** (priority order):
|
||||||
|
|
||||||
|
| Priority | Method | Frameworks |
|
||||||
|
|----------|--------|-----------|
|
||||||
|
| 1 | package.json devDependencies | vitest, jest, mocha, pytest |
|
||||||
|
| 2 | package.json scripts.test | vitest, jest, mocha, pytest |
|
||||||
|
| 3 | Config files | vitest.config.*, jest.config.*, pytest.ini |
|
||||||
|
|
||||||
|
**Affected test discovery** from executor's modified files:
|
||||||
|
- Search variants: `<name>.test.ts`, `<name>.spec.ts`, `tests/<name>.test.ts`, `__tests__/<name>.test.ts`
|
||||||
|
|
||||||
|
## Phase 3: Test Execution & Fix Cycle
|
||||||
|
|
||||||
|
**Config**: MAX_ITERATIONS=10, PASS_RATE_TARGET=95%, AFFECTED_TESTS_FIRST=true
|
||||||
|
|
||||||
|
1. Run affected tests → parse results
|
||||||
|
2. Pass rate met → run full suite
|
||||||
|
3. Failures → select strategy → fix → re-run → repeat
|
||||||
|
|
||||||
|
**Strategy selection**:
|
||||||
|
|
||||||
|
| Condition | Strategy | Behavior |
|
||||||
|
|-----------|----------|----------|
|
||||||
|
| Iteration <= 3 or pass >= 80% | Conservative | Fix one critical failure at a time |
|
||||||
|
| Critical failures < 5 | Surgical | Fix specific pattern everywhere |
|
||||||
|
| Pass < 50% or iteration > 7 | Aggressive | Fix all failures in batch |
|
||||||
|
|
||||||
|
**Test commands**:
|
||||||
|
|
||||||
|
| Framework | Affected | Full Suite |
|
||||||
|
|-----------|---------|------------|
|
||||||
|
| vitest | `vitest run <files>` | `vitest run` |
|
||||||
|
| jest | `jest <files> --no-coverage` | `jest --no-coverage` |
|
||||||
|
| pytest | `pytest <files> -v` | `pytest -v` |
|
||||||
|
|
||||||
|
## Phase 4: Result Analysis
|
||||||
|
|
||||||
|
**Failure classification**:
|
||||||
|
|
||||||
|
| Severity | Patterns |
|
||||||
|
|----------|----------|
|
||||||
|
| Critical | SyntaxError, cannot find module, undefined |
|
||||||
|
| High | Assertion failures, toBe/toEqual |
|
||||||
|
| Medium | Timeout, async errors |
|
||||||
|
| Low | Warnings, deprecations |
|
||||||
|
|
||||||
|
**Report routing**:
|
||||||
|
|
||||||
|
| Condition | Type |
|
||||||
|
|-----------|------|
|
||||||
|
| Pass rate >= target | test_result (success) |
|
||||||
|
| Pass rate < target after max iterations | fix_required |
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Framework not detected | Prompt user |
|
||||||
|
| No tests found | Report to coordinator |
|
||||||
|
| Infinite fix loop | Abort after MAX_ITERATIONS |
|
||||||
126
.claude/skills/team-lifecycle-v5/role-specs/writer.md
Normal file
126
.claude/skills/team-lifecycle-v5/role-specs/writer.md
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
---
|
||||||
|
role: writer
|
||||||
|
prefix: DRAFT
|
||||||
|
inner_loop: true
|
||||||
|
discuss_rounds: [DISCUSS-002, DISCUSS-003, DISCUSS-004, DISCUSS-005]
|
||||||
|
subagents: [discuss, doc-generation]
|
||||||
|
message_types:
|
||||||
|
success: draft_ready
|
||||||
|
revision: draft_revision
|
||||||
|
error: error
|
||||||
|
---
|
||||||
|
|
||||||
|
# Writer — Phase 2-4
|
||||||
|
|
||||||
|
## Phase 2: Context Loading
|
||||||
|
|
||||||
|
**Objective**: Load all required inputs for document generation.
|
||||||
|
|
||||||
|
### Document type routing
|
||||||
|
|
||||||
|
| Task Subject Contains | Doc Type | Template | Prior Discussion Input |
|
||||||
|
|----------------------|----------|----------|----------------------|
|
||||||
|
| Product Brief | product-brief | templates/product-brief.md | discussions/DISCUSS-001-discussion.md |
|
||||||
|
| Requirements / PRD | requirements | templates/requirements-prd.md | discussions/DISCUSS-002-discussion.md |
|
||||||
|
| Architecture | architecture | templates/architecture-doc.md | discussions/DISCUSS-003-discussion.md |
|
||||||
|
| Epics | epics | templates/epics-template.md | discussions/DISCUSS-004-discussion.md |
|
||||||
|
|
||||||
|
### Inline discuss mapping
|
||||||
|
|
||||||
|
| Doc Type | Inline Discuss Round | Perspectives |
|
||||||
|
|----------|---------------------|-------------|
|
||||||
|
| product-brief | DISCUSS-002 | product, technical, quality, coverage |
|
||||||
|
| requirements | DISCUSS-003 | quality, product, coverage |
|
||||||
|
| architecture | DISCUSS-004 | technical, risk |
|
||||||
|
| epics | DISCUSS-005 | product, technical, quality, coverage |
|
||||||
|
|
||||||
|
### Progressive dependency loading
|
||||||
|
|
||||||
|
| Doc Type | Requires |
|
||||||
|
|----------|----------|
|
||||||
|
| product-brief | discovery-context.json |
|
||||||
|
| requirements | + product-brief.md |
|
||||||
|
| architecture | + requirements/_index.md |
|
||||||
|
| epics | + architecture/_index.md |
|
||||||
|
|
||||||
|
**Prior decisions from accumulator**: Pass context_accumulator summaries as "Prior Decisions" to subagent.
|
||||||
|
|
||||||
|
| Input | Source | Required |
|
||||||
|
|-------|--------|----------|
|
||||||
|
| Document standards | `../../specs/document-standards.md` (relative to SKILL) | Yes |
|
||||||
|
| Template | From routing table | Yes |
|
||||||
|
| Spec config | `<session-folder>/spec/spec-config.json` | Yes |
|
||||||
|
| Discovery context | `<session-folder>/spec/discovery-context.json` | Yes |
|
||||||
|
| Discussion feedback | `<session-folder>/discussions/<discuss-file>` | If exists |
|
||||||
|
| Prior decisions | context_accumulator (in-memory) | If prior tasks exist |
|
||||||
|
|
||||||
|
## Phase 3: Subagent Document Generation
|
||||||
|
|
||||||
|
**Objective**: Delegate document generation to doc-generation subagent.
|
||||||
|
|
||||||
|
Do NOT execute CLI calls in main agent. Delegate to subagent:
|
||||||
|
|
||||||
|
```
|
||||||
|
Task({
|
||||||
|
subagent_type: "universal-executor",
|
||||||
|
run_in_background: false,
|
||||||
|
description: "Generate <doc-type> document",
|
||||||
|
prompt: `<from subagents/doc-generation-subagent.md>
|
||||||
|
|
||||||
|
## Task
|
||||||
|
- Document type: <doc-type>
|
||||||
|
- Session folder: <session-folder>
|
||||||
|
- Template: <template-path>
|
||||||
|
|
||||||
|
## Context
|
||||||
|
- Spec config: <spec-config content>
|
||||||
|
- Discovery context: <discovery-context summary>
|
||||||
|
- Prior discussion feedback: <discussion-file content if exists>
|
||||||
|
- Prior decisions (from writer accumulator):
|
||||||
|
<context_accumulator serialized>
|
||||||
|
|
||||||
|
## Expected Output
|
||||||
|
Return JSON:
|
||||||
|
{
|
||||||
|
"artifact_path": "<output-path>",
|
||||||
|
"summary": "<100-200 char summary>",
|
||||||
|
"key_decisions": ["<decision-1>", ...],
|
||||||
|
"sections_generated": ["<section-1>", ...],
|
||||||
|
"warnings": ["<warning if any>"]
|
||||||
|
}`
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Main agent receives only the JSON summary. Document is written to disk by subagent.
|
||||||
|
|
||||||
|
## Phase 4: Self-Validation + Inline Discuss
|
||||||
|
|
||||||
|
### 4a: Self-Validation
|
||||||
|
|
||||||
|
| Check | What to Verify |
|
||||||
|
|-------|---------------|
|
||||||
|
| has_frontmatter | Starts with YAML frontmatter |
|
||||||
|
| sections_complete | All template sections present |
|
||||||
|
| cross_references | session_id included |
|
||||||
|
| discussion_integrated | Reflects prior round feedback (if exists) |
|
||||||
|
|
||||||
|
### 4b: Inline Discuss
|
||||||
|
|
||||||
|
Call discuss subagent for this task's discuss round:
|
||||||
|
- Artifact: `<output-path>` (the generated document)
|
||||||
|
- Round: `<DISCUSS-NNN>` from mapping table
|
||||||
|
- Perspectives: from mapping table
|
||||||
|
|
||||||
|
Handle discuss verdict per team-worker consensus handling protocol.
|
||||||
|
|
||||||
|
**Report**: doc type, validation status, discuss verdict + severity, average rating, summary, output path.
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Subagent failure | Retry once with alternative subagent_type. Still fails → log error, continue next task |
|
||||||
|
| Discuss subagent fails | Skip discuss, log warning |
|
||||||
|
| Cumulative 3 task failures | SendMessage to coordinator, STOP |
|
||||||
|
| Prior doc not found | Notify coordinator, request prerequisite |
|
||||||
|
| Discussion contradicts prior docs | Note conflict, flag for coordinator |
|
||||||
@@ -100,8 +100,9 @@ Optional flags: `--team` (default: "planex"), `--exec` (execution method), `-y`/
|
|||||||
|
|
||||||
每次 SendMessage 前,先调用 `mcp__ccw-tools__team_msg` 记录:
|
每次 SendMessage 前,先调用 `mcp__ccw-tools__team_msg` 记录:
|
||||||
|
|
||||||
- 参数: operation="log", team=`<team-name>`, from=`<role>`, to=`<target-role>`, type=`<type>`, summary="[`<role>`] `<summary>`", ref=`<file_path>`
|
- 参数: operation="log", team=`<session-id>`, from=`<role>`, to=`<target-role>`, type=`<type>`, summary="[`<role>`] `<summary>`", ref=`<file_path>`
|
||||||
- **CLI fallback**: 当 MCP 不可用时 -> `ccw team log --team <team> --from <role> --to <target> --type <type> --summary "[<role>] ..." --json`
|
- **注意**: `team` 必须是 **session ID** (如 `PEX-project-2026-02-27`), 不是 team name. 从任务描述的 `Session:` 字段提取.
|
||||||
|
- **CLI fallback**: 当 MCP 不可用时 -> `ccw team log --team <session-id> --from <role> --to <target> --type <type> --summary "[<role>] ..." --json`
|
||||||
|
|
||||||
**Message types by role**:
|
**Message types by role**:
|
||||||
|
|
||||||
|
|||||||
@@ -71,10 +71,12 @@ Load solution -> Route to backend (Agent/Codex/Gemini) based on execution_method
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||||
|
|
||||||
|
**NOTE**: `team` must be **session ID** (e.g., `PEX-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "planex",
|
team: <session-id>, // e.g., "PEX-project-2026-02-27", NOT "planex"
|
||||||
from: "executor",
|
from: "executor",
|
||||||
to: "planner",
|
to: "planner",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -86,7 +88,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team planex --from executor --to planner --type <message-type> --summary \"[executor] <task-prefix> complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from executor --to planner --type <message-type> --summary \"[executor] <task-prefix> complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -281,7 +283,7 @@ Bash("ccw issue update <issueId> --status completed")
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "planex",
|
team: <session-id>, // e.g., "PEX-project-2026-02-27", NOT "planex"
|
||||||
from: "executor",
|
from: "executor",
|
||||||
to: "planner",
|
to: "planner",
|
||||||
type: "impl_complete",
|
type: "impl_complete",
|
||||||
@@ -320,7 +322,7 @@ Query for next `EXEC-*` task with owner=executor, status=pending, blockedBy empt
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "planex",
|
team: <session-id>, // e.g., "PEX-project-2026-02-27", NOT "planex"
|
||||||
from: "executor",
|
from: "executor",
|
||||||
to: "planner",
|
to: "planner",
|
||||||
type: "wave_done",
|
type: "wave_done",
|
||||||
|
|||||||
@@ -66,10 +66,12 @@ Demand decomposition -> Issue creation -> Solution design -> Conflict check -> E
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
||||||
|
|
||||||
|
**NOTE**: `team` must be **session ID** (e.g., `PEX-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "planex",
|
team: <session-id>, // e.g., "PEX-project-2026-02-27", NOT "planex"
|
||||||
from: "planner",
|
from: "planner",
|
||||||
to: "executor",
|
to: "executor",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -81,7 +83,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team planex --from planner --to executor --type <message-type> --summary \"[planner] <task-prefix> complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from planner --to executor --type <message-type> --summary \"[planner] <task-prefix> complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -248,7 +250,7 @@ Perform conflict detection using files_touched overlap analysis.
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "planex", from: "planner", to: "executor",
|
operation: "log", team: <session-id>, from: "planner", to: "executor", // team = session ID
|
||||||
type: "wave_ready",
|
type: "wave_ready",
|
||||||
summary: "[planner] Wave <waveNum> fully dispatched: <issueCount> issues"
|
summary: "[planner] Wave <waveNum> fully dispatched: <issueCount> issues"
|
||||||
})
|
})
|
||||||
@@ -269,7 +271,7 @@ SendMessage({
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "planex",
|
team: <session-id>, // e.g., "PEX-project-2026-02-27", NOT "planex"
|
||||||
from: "planner",
|
from: "planner",
|
||||||
to: "executor",
|
to: "executor",
|
||||||
type: "all_planned",
|
type: "all_planned",
|
||||||
|
|||||||
@@ -135,8 +135,9 @@ Every worker executes the same task discovery flow on startup:
|
|||||||
Standard reporting flow after task completion:
|
Standard reporting flow after task completion:
|
||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Parameters: operation="log", team="quality-assurance", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Parameters: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable -> `ccw team log --team quality-assurance --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **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>]`)
|
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
||||||
3. **TaskUpdate**: Mark task completed
|
3. **TaskUpdate**: Mark task completed
|
||||||
4. **Loop**: Return to Phase 1 to check next task
|
4. **Loop**: Return to Phase 1 to check next task
|
||||||
|
|||||||
@@ -56,10 +56,12 @@ Quality analyst. Analyze defect patterns, coverage gaps, test effectiveness, and
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
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({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "quality-assurance",
|
team: <session-id>, // e.g., "TQA-project-2026-02-27", NOT "quality-assurance"
|
||||||
from: "analyst",
|
from: "analyst",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -71,7 +73,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team quality-assurance --from analyst --to coordinator --type <message-type> --summary \"[analyst] analysis complete\" --ref <report-path> --json")
|
Bash("ccw team log --team <session-id> --from analyst --to coordinator --type <message-type> --summary \"[analyst] analysis complete\" --ref <report-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
> 任务链创建与依赖管理。根据 QA 模式创建 pipeline 任务链并分配给 worker 角色。
|
> 任务链创建与依赖管理。根据 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
|
## When to Use
|
||||||
|
|
||||||
- Phase 3 of Coordinator
|
- Phase 3 of Coordinator
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
> 阶段驱动的协调循环。按 pipeline 阶段顺序等待 worker 完成,路由消息,触发 GC 循环,执行质量门控。
|
> 阶段驱动的协调循环。按 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
|
## When to Use
|
||||||
|
|
||||||
- Phase 4 of Coordinator
|
- Phase 4 of Coordinator
|
||||||
|
|||||||
@@ -57,10 +57,12 @@ Test executor. Run test suites, collect coverage data, and perform automatic fix
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
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({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "quality-assurance",
|
team: <session-id>, // e.g., "TQA-project-2026-02-27", NOT "quality-assurance"
|
||||||
from: "executor",
|
from: "executor",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -73,7 +75,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team quality-assurance --from executor --to coordinator --type <message-type> --summary \"[executor] test execution complete\" --ref <results-file> --json")
|
Bash("ccw team log --team <session-id> --from executor --to coordinator --type <message-type> --summary \"[executor] test execution complete\" --ref <results-file> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -57,10 +57,12 @@ Test case generator. Generate test code according to strategist's strategy and l
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
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({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "quality-assurance",
|
team: <session-id>, // e.g., "TQA-project-2026-02-27", NOT "quality-assurance"
|
||||||
from: "generator",
|
from: "generator",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -72,7 +74,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team quality-assurance --from generator --to coordinator --type <message-type> --summary \"[generator] test generation complete\" --ref <test-file> --json")
|
Bash("ccw team log --team <session-id> --from generator --to coordinator --type <message-type> --summary \"[generator] test generation complete\" --ref <test-file> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -55,10 +55,12 @@ Test strategist. Analyze change scope, determine test layers (L1-L3), define cov
|
|||||||
|
|
||||||
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
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({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "quality-assurance",
|
team: <session-id>, // e.g., "TQA-project-2026-02-27", NOT "quality-assurance"
|
||||||
from: "strategist",
|
from: "strategist",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -70,7 +72,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team quality-assurance --from strategist --to coordinator --type <message-type> --summary \"[strategist] QASTRAT complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from strategist --to coordinator --type <message-type> --summary \"[strategist] QASTRAT complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
|
|
||||||
if (!workerConfig) {
|
if (!workerConfig) {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., RC-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "error",
|
to: "user", type: "error",
|
||||||
summary: `[coordinator] Unknown stage prefix: ${stagePrefix}, skipping`
|
summary: `[coordinator] Unknown stage prefix: ${stagePrefix}, skipping`
|
||||||
})
|
})
|
||||||
@@ -66,7 +66,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
TaskUpdate({ taskId: stageTask.id, status: 'in_progress' })
|
TaskUpdate({ taskId: stageTask.id, status: 'in_progress' })
|
||||||
|
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., RC-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: workerConfig.role, type: "stage_transition",
|
to: workerConfig.role, type: "stage_transition",
|
||||||
summary: `[coordinator] Starting stage: ${stageTask.subject} -> ${workerConfig.role}`
|
summary: `[coordinator] Starting stage: ${stageTask.subject} -> ${workerConfig.role}`
|
||||||
})
|
})
|
||||||
@@ -86,7 +86,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
if (action === 'skip') continue
|
if (action === 'skip') continue
|
||||||
} else {
|
} else {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., RC-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "stage_transition",
|
to: "user", type: "stage_transition",
|
||||||
summary: `[coordinator] Stage complete: ${stageTask.subject}`
|
summary: `[coordinator] Stage complete: ${stageTask.subject}`
|
||||||
})
|
})
|
||||||
@@ -96,7 +96,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
if (stagePrefix === 'SCAN') {
|
if (stagePrefix === 'SCAN') {
|
||||||
const mem = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
const mem = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
|
||||||
if ((mem.findings_count || 0) === 0) {
|
if ((mem.findings_count || 0) === 0) {
|
||||||
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "coordinator",
|
mcp__ccw-tools__team_msg({ operation: "log", team: sessionId // MUST be session ID (e.g., RC-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "pipeline_complete",
|
to: "user", type: "pipeline_complete",
|
||||||
summary: `[coordinator] 0 findings. Code is clean. Skipping review/fix.` })
|
summary: `[coordinator] 0 findings. Code is clean. Skipping review/fix.` })
|
||||||
for (const r of pipelineTasks.slice(pipelineTasks.indexOf(stageTask) + 1))
|
for (const r of pipelineTasks.slice(pipelineTasks.indexOf(stageTask) + 1))
|
||||||
@@ -163,7 +163,7 @@ function buildWorkerArgs(stageTask, workerConfig) {
|
|||||||
```javascript
|
```javascript
|
||||||
function handleStageFailure(stageTask, taskState, workerConfig, autoYes) {
|
function handleStageFailure(stageTask, taskState, workerConfig, autoYes) {
|
||||||
if (autoYes) {
|
if (autoYes) {
|
||||||
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "coordinator",
|
mcp__ccw-tools__team_msg({ operation: "log", team: sessionId // MUST be session ID (e.g., RC-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "error",
|
to: "user", type: "error",
|
||||||
summary: `[coordinator] [auto] ${stageTask.subject} incomplete, skipping` })
|
summary: `[coordinator] [auto] ${stageTask.subject} incomplete, skipping` })
|
||||||
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
|
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
|
||||||
@@ -191,7 +191,7 @@ function handleStageFailure(stageTask, taskState, workerConfig, autoYes) {
|
|||||||
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
|
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
|
||||||
return 'skip'
|
return 'skip'
|
||||||
} else {
|
} else {
|
||||||
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "coordinator",
|
mcp__ccw-tools__team_msg({ operation: "log", team: sessionId // MUST be session ID (e.g., RC-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "error",
|
to: "user", type: "error",
|
||||||
summary: `[coordinator] User aborted at: ${stageTask.subject}` })
|
summary: `[coordinator] User aborted at: ${stageTask.subject}` })
|
||||||
return 'abort'
|
return 'abort'
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "team-review",
|
team: <session-id>, // MUST be session ID (e.g., RC-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "coordinator",
|
from: "coordinator",
|
||||||
to: "user",
|
to: "user",
|
||||||
type: "dispatch_ready",
|
type: "dispatch_ready",
|
||||||
@@ -97,7 +97,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team team-review --from coordinator --to user --type dispatch_ready --summary \"[coordinator] Task chain created\" --json")
|
Bash("ccw team log --team <session-id> --from coordinator --to user --type dispatch_ready --summary \"[coordinator] Task chain created\" --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "team-review",
|
team: <session-id>, // MUST be session ID (e.g., RC-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "fixer",
|
from: "fixer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "fix_complete",
|
type: "fix_complete",
|
||||||
@@ -79,7 +79,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team team-review --from fixer --to coordinator --type fix_complete --summary \"[fixer] Fix complete\" --ref <path> --json")
|
Bash("ccw team log --team <session-id> --from fixer --to coordinator --type fix_complete --summary \"[fixer] Fix complete\" --ref <path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "team-review",
|
team: <session-id>, // MUST be session ID (e.g., RC-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "reviewer",
|
from: "reviewer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "review_complete",
|
type: "review_complete",
|
||||||
@@ -78,7 +78,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team team-review --from reviewer --to coordinator --type review_complete --summary \"[reviewer] Review complete\" --ref <path> --json")
|
Bash("ccw team log --team <session-id> --from reviewer --to coordinator --type review_complete --summary \"[reviewer] Review complete\" --ref <path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "team-review",
|
team: <session-id>, // MUST be session ID (e.g., RC-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "scanner",
|
from: "scanner",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "scan_complete",
|
type: "scan_complete",
|
||||||
@@ -79,7 +79,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team team-review --from scanner --to coordinator --type scan_complete --summary \"[scanner] Scan complete\" --ref <path> --json")
|
Bash("ccw team log --team <session-id> --from scanner --to coordinator --type scan_complete --summary \"[scanner] Scan complete\" --ref <path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ Edit(`${sessionFolder}/state.md`, {
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "roadmap-dev",
|
operation: "log", team: sessionId, // MUST be session ID (e.g., RD-xxx-date), NOT team name
|
||||||
from: "coordinator", to: "all",
|
from: "coordinator", to: "all",
|
||||||
type: "phase_started",
|
type: "phase_started",
|
||||||
summary: `[coordinator] Phase ${phaseNumber} dispatched: PLAN-${phaseNumber}01 → EXEC-${phaseNumber}01 → VERIFY-${phaseNumber}01`,
|
summary: `[coordinator] Phase ${phaseNumber} dispatched: PLAN-${phaseNumber}01 → EXEC-${phaseNumber}01 → VERIFY-${phaseNumber}01`,
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ function triggerGapClosure(phase, iteration, gaps, sessionFolder) {
|
|||||||
|
|
||||||
// Log gap closure initiation
|
// Log gap closure initiation
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "roadmap-dev",
|
operation: "log", team: sessionId // MUST be session ID (e.g., RD-xxx-date), NOT team name,
|
||||||
from: "coordinator", to: "planner",
|
from: "coordinator", to: "planner",
|
||||||
type: "gap_closure",
|
type: "gap_closure",
|
||||||
summary: `[coordinator] Gap closure iteration ${iteration} for phase ${phase}: ${gaps.length} gaps`,
|
summary: `[coordinator] Gap closure iteration ${iteration} for phase ${phase}: ${gaps.length} gaps`,
|
||||||
@@ -334,7 +334,7 @@ function updateStatePhaseComplete(phase, sessionFolder) {
|
|||||||
```javascript
|
```javascript
|
||||||
// All phases done -- return control to coordinator Phase 5 (Report + Persist)
|
// All phases done -- return control to coordinator Phase 5 (Report + Persist)
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "roadmap-dev",
|
operation: "log", team: sessionId // MUST be session ID (e.g., RD-xxx-date), NOT team name,
|
||||||
from: "coordinator", to: "all",
|
from: "coordinator", to: "all",
|
||||||
type: "project_complete",
|
type: "project_complete",
|
||||||
summary: `[coordinator] All ${totalPhases} phases complete.`,
|
summary: `[coordinator] All ${totalPhases} phases complete.`,
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "roadmap-dev",
|
team: <session-id>, // MUST be session ID (e.g., RD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "coordinator",
|
from: "coordinator",
|
||||||
to: <target-role>,
|
to: <target-role>,
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -104,7 +104,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team roadmap-dev --from coordinator --to <target> --type <type> --summary \"[coordinator] <summary>\" --json")
|
Bash("ccw team log --team <session-id> --from coordinator --to <target> --type <type> --summary \"[coordinator] <summary>\" --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "roadmap-dev",
|
team: <session-id>, // MUST be session ID (e.g., RD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "executor",
|
from: "executor",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -81,7 +81,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team roadmap-dev --from executor --to coordinator --type <type> --summary \"[executor] <summary>\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from executor --to coordinator --type <type> --summary \"[executor] <summary>\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "roadmap-dev",
|
team: <session-id>, // MUST be session ID (e.g., RD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "planner",
|
from: "planner",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -83,7 +83,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team roadmap-dev --from planner --to coordinator --type <type> --summary \"[planner] <summary>\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from planner --to coordinator --type <type> --summary \"[planner] <summary>\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "roadmap-dev",
|
team: <session-id>, // MUST be session ID (e.g., RD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "verifier",
|
from: "verifier",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -82,7 +82,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team roadmap-dev --from verifier --to coordinator --type <type> --summary \"[verifier] <summary>\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from verifier --to coordinator --type <type> --summary \"[verifier] <summary>\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: <session-id>, // MUST be session ID (e.g., TD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "assessor",
|
from: "assessor",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -70,7 +70,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from assessor --to coordinator --type <message-type> --summary \"[assessor] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from assessor --to coordinator --type <message-type> --summary \"[assessor] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ const chainValid = chainTasks.length === pipeline.length
|
|||||||
|
|
||||||
if (!chainValid) {
|
if (!chainValid) {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId, from: "coordinator", // team must be session ID (e.g., TD-xxx-date), NOT team name
|
||||||
to: "user", type: "error",
|
to: "user", type: "error",
|
||||||
summary: `[coordinator] 任务链创建不完整: ${chainTasks.length}/${pipeline.length}`
|
summary: `[coordinator] 任务链创建不完整: ${chainTasks.length}/${pipeline.length}`
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
|
|
||||||
if (!workerConfig) {
|
if (!workerConfig) {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "error",
|
to: "user", type: "error",
|
||||||
summary: `[coordinator] 未知阶段前缀: ${stagePrefix},跳过`
|
summary: `[coordinator] 未知阶段前缀: ${stagePrefix},跳过`
|
||||||
})
|
})
|
||||||
@@ -87,7 +87,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
TaskUpdate({ taskId: stageTask.id, status: 'in_progress' })
|
TaskUpdate({ taskId: stageTask.id, status: 'in_progress' })
|
||||||
|
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: workerConfig.role, type: "task_unblocked",
|
to: workerConfig.role, type: "task_unblocked",
|
||||||
summary: `[coordinator] 启动阶段: ${stageTask.subject} → ${workerConfig.role}`
|
summary: `[coordinator] 启动阶段: ${stageTask.subject} → ${workerConfig.role}`
|
||||||
})
|
})
|
||||||
@@ -111,7 +111,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
handleStageFailure(stageTask, taskState, workerConfig, autoYes)
|
handleStageFailure(stageTask, taskState, workerConfig, autoYes)
|
||||||
} else {
|
} else {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "quality_gate",
|
to: "user", type: "quality_gate",
|
||||||
summary: `[coordinator] 阶段完成: ${stageTask.subject}`
|
summary: `[coordinator] 阶段完成: ${stageTask.subject}`
|
||||||
})
|
})
|
||||||
@@ -127,7 +127,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "plan_approval",
|
to: "user", type: "plan_approval",
|
||||||
summary: `[coordinator] 治理方案已生成,等待审批`
|
summary: `[coordinator] 治理方案已生成,等待审批`
|
||||||
})
|
})
|
||||||
@@ -166,7 +166,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
continue // 跳到下一阶段(即刚插入的修订任务)
|
continue // 跳到下一阶段(即刚插入的修订任务)
|
||||||
} else if (planDecision === "终止") {
|
} else if (planDecision === "终止") {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "shutdown",
|
to: "user", type: "shutdown",
|
||||||
summary: `[coordinator] 用户终止流水线(方案审批阶段)`
|
summary: `[coordinator] 用户终止流水线(方案审批阶段)`
|
||||||
})
|
})
|
||||||
@@ -194,7 +194,7 @@ for (const stageTask of pipelineTasks) {
|
|||||||
worktreeCreated = true
|
worktreeCreated = true
|
||||||
|
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "worktree_created",
|
to: "user", type: "worktree_created",
|
||||||
summary: `[coordinator] Worktree 已创建: ${worktreePath} (branch: ${branchName})`
|
summary: `[coordinator] Worktree 已创建: ${worktreePath} (branch: ${branchName})`
|
||||||
})
|
})
|
||||||
@@ -266,7 +266,7 @@ ${worktreeSection}
|
|||||||
function handleStageFailure(stageTask, taskState, workerConfig, autoYes) {
|
function handleStageFailure(stageTask, taskState, workerConfig, autoYes) {
|
||||||
if (autoYes) {
|
if (autoYes) {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "error",
|
to: "user", type: "error",
|
||||||
summary: `[coordinator] [auto] 阶段 ${stageTask.subject} 未完成 (status=${taskState.status}),自动跳过`
|
summary: `[coordinator] [auto] 阶段 ${stageTask.subject} 未完成 (status=${taskState.status}),自动跳过`
|
||||||
})
|
})
|
||||||
@@ -309,7 +309,7 @@ function handleStageFailure(stageTask, taskState, workerConfig, autoYes) {
|
|||||||
return 'skip'
|
return 'skip'
|
||||||
} else {
|
} else {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "shutdown",
|
to: "user", type: "shutdown",
|
||||||
summary: `[coordinator] 用户终止流水线,当前阶段: ${stageTask.subject}`
|
summary: `[coordinator] 用户终止流水线,当前阶段: ${stageTask.subject}`
|
||||||
})
|
})
|
||||||
@@ -333,7 +333,7 @@ function evaluateValidationResult(sessionFolder) {
|
|||||||
else if (!improved) status = 'CONDITIONAL'
|
else if (!improved) status = 'CONDITIONAL'
|
||||||
|
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "quality_gate",
|
to: "user", type: "quality_gate",
|
||||||
summary: `[coordinator] 质量门控: ${status} (债务分 ${debtBefore} → ${debtAfter}, 回归 ${regressions})`
|
summary: `[coordinator] 质量门控: ${status} (债务分 ${debtBefore} → ${debtAfter}, 回归 ${regressions})`
|
||||||
})
|
})
|
||||||
@@ -387,7 +387,7 @@ EOF
|
|||||||
)"`)
|
)"`)
|
||||||
|
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "pr_created",
|
to: "user", type: "pr_created",
|
||||||
summary: `[coordinator] PR 已创建: branch ${branch}`
|
summary: `[coordinator] PR 已创建: branch ${branch}`
|
||||||
})
|
})
|
||||||
@@ -396,7 +396,7 @@ EOF
|
|||||||
Bash(`git worktree remove "${wtPath}" 2>/dev/null || true`)
|
Bash(`git worktree remove "${wtPath}" 2>/dev/null || true`)
|
||||||
} else if (finalSharedMemory.worktree && !finalSharedMemory.validation_results?.passed) {
|
} else if (finalSharedMemory.worktree && !finalSharedMemory.validation_results?.passed) {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId // MUST be session ID (e.g., TD-xxx-date), NOT team name, from: "coordinator",
|
||||||
to: "user", type: "quality_gate",
|
to: "user", type: "quality_gate",
|
||||||
summary: `[coordinator] 验证未通过,worktree 保留于 ${finalSharedMemory.worktree.path},请手动检查`
|
summary: `[coordinator] 验证未通过,worktree 保留于 ${finalSharedMemory.worktree.path},请手动检查`
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: <session-id>, // MUST be session ID (e.g., TD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "coordinator",
|
from: "coordinator",
|
||||||
to: "user",
|
to: "user",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -98,7 +98,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from coordinator --to user --type <message-type> --summary \"[coordinator] ...\" --json")
|
Bash("ccw team log --team <session-id> --from coordinator --to user --type <message-type> --summary \"[coordinator] ...\" --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: <session-id>, // MUST be session ID (e.g., TD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "executor",
|
from: "executor",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -73,7 +73,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from executor --to coordinator --type <message-type> --summary \"[executor] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from executor --to coordinator --type <message-type> --summary \"[executor] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: <session-id>, // MUST be session ID (e.g., TD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "planner",
|
from: "planner",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -70,7 +70,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from planner --to coordinator --type <message-type> --summary \"[planner] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from planner --to coordinator --type <message-type> --summary \"[planner] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: <session-id>, // MUST be session ID (e.g., TD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "scanner",
|
from: "scanner",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -70,7 +70,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from scanner --to coordinator --type <message-type> --summary \"[scanner] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from scanner --to coordinator --type <message-type> --summary \"[scanner] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: <team-name>,
|
team: <session-id>, // MUST be session ID (e.g., TD-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "validator",
|
from: "validator",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -71,7 +71,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team <team-name> --from validator --to coordinator --type <message-type> --summary \"[validator] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from validator --to coordinator --type <message-type> --summary \"[validator] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ Standard reporting flow after task completion:
|
|||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Parameters: operation="log", team="testing", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Parameters: operation="log", team="testing", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable → `ccw team log --team testing --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **CLI fallback**: When MCP unavailable → `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json` // team must be session ID
|
||||||
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
||||||
3. **TaskUpdate**: Mark task completed
|
3. **TaskUpdate**: Mark task completed
|
||||||
4. **Loop**: Return to Phase 1 to check next task
|
4. **Loop**: Return to Phase 1 to check next task
|
||||||
@@ -142,9 +142,11 @@ All outputs must carry `[role_name]` prefix in both SendMessage content/summary
|
|||||||
|
|
||||||
Every SendMessage **before**, must call `mcp__ccw-tools__team_msg` to log:
|
Every SendMessage **before**, must call `mcp__ccw-tools__team_msg` to log:
|
||||||
|
|
||||||
**Parameters**: operation="log", team="testing", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
**Parameters**: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
|
|
||||||
**CLI fallback**: When MCP unavailable → `ccw team log --team testing --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
> **CRITICAL**: `team` must be session ID (e.g., TST-xxx-date), 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`
|
||||||
|
|
||||||
**Message types by role**:
|
**Message types by role**:
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "testing",
|
team: <session-id>, // MUST be session ID (e.g., TST-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "analyst",
|
from: "analyst",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -69,7 +69,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team testing --from analyst --to coordinator --type <message-type> --summary \"[analyst] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from analyst --to coordinator --type <message-type> --summary \"[analyst] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -215,7 +215,7 @@ Write("<session-folder>/shared-memory.json", <updated-json>)
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "testing", from: "analyst", to: "coordinator",
|
operation: "log", team: <session-id> // MUST be session ID, NOT team name, from: "analyst", to: "coordinator",
|
||||||
type: "analysis_ready",
|
type: "analysis_ready",
|
||||||
summary: "[analyst] Quality report: score <score>/10, <pattern-count> defect patterns, <gap-count> coverage gaps",
|
summary: "[analyst] Quality report: score <score>/10, <pattern-count> defect patterns, <gap-count> coverage gaps",
|
||||||
ref: "<session-folder>/analysis/quality-report.md"
|
ref: "<session-folder>/analysis/quality-report.md"
|
||||||
|
|||||||
@@ -237,7 +237,9 @@ When receiving `tests_failed` or `coverage_report`:
|
|||||||
**GC Loop trigger message**:
|
**GC Loop trigger message**:
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "testing", from: "coordinator", to: "generator",
|
operation: "log",
|
||||||
|
team: <session-id>, // MUST be session ID (e.g., TST-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
|
from: "coordinator", to: "generator",
|
||||||
type: "gc_loop_trigger",
|
type: "gc_loop_trigger",
|
||||||
summary: "[coordinator] GC round <N>: coverage <X>% < target <Y>%, revise tests"
|
summary: "[coordinator] GC round <N>: coverage <X>% < target <Y>%, revise tests"
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "testing",
|
team: <session-id>, // MUST be session ID (e.g., TST-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "executor",
|
from: "executor",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -74,7 +74,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team testing --from executor --to coordinator --type <message-type> --summary \"[executor] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from executor --to coordinator --type <message-type> --summary \"[executor] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -248,7 +248,7 @@ Write("<session-folder>/shared-memory.json", <updated-json>)
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "testing", from: "executor", to: "coordinator",
|
operation: "log", team: <session-id> // MUST be session ID, NOT team name, from: "executor", to: "coordinator",
|
||||||
type: <passed ? "tests_passed" : "tests_failed">,
|
type: <passed ? "tests_passed" : "tests_failed">,
|
||||||
summary: "[executor] <passed|failed>: pass=<pass_rate>%, coverage=<coverage>% (target: <target>%), iterations=<N>",
|
summary: "[executor] <passed|failed>: pass=<pass_rate>%, coverage=<coverage>% (target: <target>%), iterations=<N>",
|
||||||
ref: "<session-folder>/results/run-<N>.json"
|
ref: "<session-folder>/results/run-<N>.json"
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "testing",
|
team: <session-id>, // MUST be session ID (e.g., TST-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "generator",
|
from: "generator",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -74,7 +74,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team testing --from generator --to coordinator --type <message-type> --summary \"[generator] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from generator --to coordinator --type <message-type> --summary \"[generator] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -232,7 +232,7 @@ Write("<session-folder>/shared-memory.json", <updated-json>)
|
|||||||
|
|
||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: "testing", from: "generator", to: "coordinator",
|
operation: "log", team: <session-id> // MUST be session ID, NOT team name, from: "generator", to: "coordinator",
|
||||||
type: <is-revision ? "tests_revised" : "tests_generated">,
|
type: <is-revision ? "tests_revised" : "tests_generated">,
|
||||||
summary: "[generator] <Generated|Revised> <file-count> <layer> test files",
|
summary: "[generator] <Generated|Revised> <file-count> <layer> test files",
|
||||||
ref: "<session-folder>/tests/<layer>/"
|
ref: "<session-folder>/tests/<layer>/"
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "testing",
|
team: <session-id>, // MUST be session ID (e.g., TST-xxx-date), NOT team name. Extract from Session: field in task description.
|
||||||
from: "strategist",
|
from: "strategist",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -70,7 +70,7 @@ mcp__ccw-tools__team_msg({
|
|||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team testing --from strategist --to coordinator --type <message-type> --summary \"[strategist] ...\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from strategist --to coordinator --type <message-type> --summary \"[strategist] ...\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -101,8 +101,9 @@ Every worker executes the same task discovery flow on startup:
|
|||||||
Standard reporting flow after task completion:
|
Standard reporting flow after task completion:
|
||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Parameters: operation="log", team="uidesign", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Parameters: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable → `ccw team log --team uidesign --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **Note**: `team` must be session ID (e.g., `UDS-xxx-date`), 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>]`)
|
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
|
||||||
3. **TaskUpdate**: Mark task completed
|
3. **TaskUpdate**: Mark task completed
|
||||||
4. **Loop**: Return to Phase 1 to check next task
|
4. **Loop**: Return to Phase 1 to check next task
|
||||||
@@ -142,9 +143,11 @@ All outputs must carry `[role_name]` prefix in both SendMessage content/summary
|
|||||||
|
|
||||||
Every SendMessage **before**, must call `mcp__ccw-tools__team_msg` to log:
|
Every SendMessage **before**, must call `mcp__ccw-tools__team_msg` to log:
|
||||||
|
|
||||||
**Parameters**: operation="log", team="uidesign", from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
**Parameters**: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
|
|
||||||
**CLI fallback**: When MCP unavailable → `ccw team log --team uidesign --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
> **Note**: `team` must be session ID (e.g., `UDS-xxx-date`), 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`
|
||||||
|
|
||||||
**Message types by role**:
|
**Message types by role**:
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "uidesign",
|
team: <session-id>,
|
||||||
from: "designer",
|
from: "designer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -68,10 +68,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UDS-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team uidesign --from designer --to coordinator --type <message-type> --summary \"[designer] DESIGN complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from designer --to coordinator --type <message-type> --summary \"[designer] DESIGN complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "uidesign",
|
team: <session-id>,
|
||||||
from: "implementer",
|
from: "implementer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -70,10 +70,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UDS-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team uidesign --from implementer --to coordinator --type <message-type> --summary \"[implementer] BUILD complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from implementer --to coordinator --type <message-type> --summary \"[implementer] BUILD complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "uidesign",
|
team: <session-id>,
|
||||||
from: "researcher",
|
from: "researcher",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -68,10 +68,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UDS-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team uidesign --from researcher --to coordinator --type <message-type> --summary \"[researcher] RESEARCH complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from researcher --to coordinator --type <message-type> --summary \"[researcher] RESEARCH complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "uidesign",
|
team: <session-id>,
|
||||||
from: "reviewer",
|
from: "reviewer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: <message-type>,
|
type: <message-type>,
|
||||||
@@ -67,10 +67,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UDS-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team uidesign --from reviewer --to coordinator --type <message-type> --summary \"[reviewer] AUDIT complete\" --ref <artifact-path> --json")
|
Bash("ccw team log --team <session-id> --from reviewer --to coordinator --type <message-type> --summary \"[reviewer] AUDIT complete\" --ref <artifact-path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -130,8 +130,9 @@ Each worker executes the same task discovery flow on startup:
|
|||||||
Standard report flow after task completion:
|
Standard report flow after task completion:
|
||||||
|
|
||||||
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
|
||||||
- Parameters: operation="log", team=<team-name>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
- Parameters: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
|
||||||
- **CLI fallback**: When MCP unavailable -> `ccw team log --team <team> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
|
- **Note**: `team` must be session ID (e.g., `UAN-xxx-date`), 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 (both content and summary prefixed with `[<role>]`)
|
2. **SendMessage**: Send result to coordinator (both content and summary prefixed with `[<role>]`)
|
||||||
3. **TaskUpdate**: Mark task completed
|
3. **TaskUpdate**: Mark task completed
|
||||||
4. **Loop**: Return to Phase 1 to check for next task
|
4. **Loop**: Return to Phase 1 to check for next task
|
||||||
@@ -179,7 +180,9 @@ On startup, read the file. After completing work, update own field and write bac
|
|||||||
|
|
||||||
### Message Bus (All Roles)
|
### Message Bus (All Roles)
|
||||||
|
|
||||||
All roles log messages before sending via SendMessage. Call `mcp__ccw-tools__team_msg` with: operation="log", team=<team-name>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<file-path>.
|
All roles log messages before sending via SendMessage. Call `mcp__ccw-tools__team_msg` with: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<file-path>.
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UAN-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
| Role | Types |
|
| Role | Types |
|
||||||
|------|-------|
|
|------|-------|
|
||||||
@@ -189,7 +192,9 @@ All roles log messages before sending via SendMessage. Call `mcp__ccw-tools__tea
|
|||||||
| discussant | `discussion_processed`, `error` |
|
| discussant | `discussion_processed`, `error` |
|
||||||
| synthesizer | `synthesis_ready`, `error` |
|
| synthesizer | `synthesis_ready`, `error` |
|
||||||
|
|
||||||
**CLI fallback**: When MCP unavailable -> `ccw team log --team "<team>" --from "<role>" --to "coordinator" --type "<type>" --summary "<summary>" --json`
|
**CLI fallback**: When MCP unavailable -> `ccw team log --team "<session-id>" --from "<role>" --to "coordinator" --type "<type>" --summary "<summary>" --json`
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UAN-xxx-date`), NOT team name.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "ultra-analyze",
|
team: <session-id>,
|
||||||
from: "analyst",
|
from: "analyst",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "analysis_ready",
|
type: "analysis_ready",
|
||||||
@@ -81,10 +81,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UAN-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team ultra-analyze --from analyst --to coordinator --type analysis_ready --summary \"[analyst] ...\" --ref <path> --json")
|
Bash("ccw team log --team <session-id> --from analyst --to coordinator --type analysis_ready --summary \"[analyst] ...\" --ref <path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ const chainValid = chainTasks.length === pipeline.length
|
|||||||
|
|
||||||
if (!chainValid) {
|
if (!chainValid) {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId, from: "coordinator",
|
||||||
to: "user", type: "error",
|
to: "user", type: "error",
|
||||||
summary: `[coordinator] 任务链创建不完整: ${chainTasks.length}/${pipeline.length}`
|
summary: `[coordinator] 任务链创建不完整: ${chainTasks.length}/${pipeline.length}`
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ for (const stageTask of preDiscussionTasks) {
|
|||||||
TaskUpdate({ taskId: stageTask.id, status: 'in_progress' })
|
TaskUpdate({ taskId: stageTask.id, status: 'in_progress' })
|
||||||
|
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId, from: "coordinator",
|
||||||
to: workerConfig.role, type: "task_unblocked",
|
to: workerConfig.role, type: "task_unblocked",
|
||||||
summary: `[coordinator] 启动阶段: ${stageTask.subject} → ${workerConfig.role}`
|
summary: `[coordinator] 启动阶段: ${stageTask.subject} → ${workerConfig.role}`
|
||||||
})
|
})
|
||||||
@@ -142,7 +142,7 @@ Skill(skill="team-ultra-analyze", args="${workerConfig.skillArgs}")
|
|||||||
handleStageTimeout(stageTask, 0, autoYes)
|
handleStageTimeout(stageTask, 0, autoYes)
|
||||||
} else {
|
} else {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId, from: "coordinator",
|
||||||
to: "user", type: "quality_gate",
|
to: "user", type: "quality_gate",
|
||||||
summary: `[coordinator] 阶段完成: ${stageTask.subject}`
|
summary: `[coordinator] 阶段完成: ${stageTask.subject}`
|
||||||
})
|
})
|
||||||
@@ -356,7 +356,7 @@ ${data.updated_understanding || '(Updated by discussant)'}
|
|||||||
function handleStageTimeout(stageTask, _unused, autoYes) {
|
function handleStageTimeout(stageTask, _unused, autoYes) {
|
||||||
if (autoYes) {
|
if (autoYes) {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId, from: "coordinator",
|
||||||
to: "user", type: "error",
|
to: "user", type: "error",
|
||||||
summary: `[coordinator] [auto] 阶段 ${stageTask.subject} worker 返回但未完成,自动跳过`
|
summary: `[coordinator] [auto] 阶段 ${stageTask.subject} worker 返回但未完成,自动跳过`
|
||||||
})
|
})
|
||||||
@@ -382,7 +382,7 @@ function handleStageTimeout(stageTask, _unused, autoYes) {
|
|||||||
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
|
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
|
||||||
} else if (answer === "终止流水线") {
|
} else if (answer === "终止流水线") {
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log", team: teamName, from: "coordinator",
|
operation: "log", team: sessionId, from: "coordinator",
|
||||||
to: "user", type: "shutdown",
|
to: "user", type: "shutdown",
|
||||||
summary: `[coordinator] 用户终止流水线,当前阶段: ${stageTask.subject}`
|
summary: `[coordinator] 用户终止流水线,当前阶段: ${stageTask.subject}`
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "ultra-analyze",
|
team: <session-id>,
|
||||||
from: "coordinator",
|
from: "coordinator",
|
||||||
to: "<recipient>",
|
to: "<recipient>",
|
||||||
type: "<message-type>",
|
type: "<message-type>",
|
||||||
@@ -79,10 +79,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UAN-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team ultra-analyze --from coordinator --to <recipient> --type <type> --summary \"[coordinator] ...\" --ref <path> --json")
|
Bash("ccw team log --team <session-id> --from coordinator --to <recipient> --type <type> --summary \"[coordinator] ...\" --ref <path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "ultra-analyze",
|
team: <session-id>,
|
||||||
from: "discussant",
|
from: "discussant",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "discussion_processed",
|
type: "discussion_processed",
|
||||||
@@ -80,10 +80,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UAN-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team ultra-analyze --from discussant --to coordinator --type discussion_processed --summary \"[discussant] ...\" --ref <path> --json")
|
Bash("ccw team log --team <session-id> --from discussant --to coordinator --type discussion_processed --summary \"[discussant] ...\" --ref <path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "ultra-analyze",
|
team: <session-id>,
|
||||||
from: "explorer",
|
from: "explorer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "exploration_ready",
|
type: "exploration_ready",
|
||||||
@@ -73,10 +73,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UAN-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team ultra-analyze --from explorer --to coordinator --type exploration_ready --summary \"[explorer] ...\" --ref <path> --json")
|
Bash("ccw team log --team <session-id> --from explorer --to coordinator --type exploration_ready --summary \"[explorer] ...\" --ref <path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
|
|||||||
```
|
```
|
||||||
mcp__ccw-tools__team_msg({
|
mcp__ccw-tools__team_msg({
|
||||||
operation: "log",
|
operation: "log",
|
||||||
team: "ultra-analyze",
|
team: <session-id>,
|
||||||
from: "synthesizer",
|
from: "synthesizer",
|
||||||
to: "coordinator",
|
to: "coordinator",
|
||||||
type: "synthesis_ready",
|
type: "synthesis_ready",
|
||||||
@@ -74,10 +74,12 @@ mcp__ccw-tools__team_msg({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note**: `team` must be session ID (e.g., `UAN-xxx-date`), NOT team name. Extract from `Session:` field in task description.
|
||||||
|
|
||||||
**CLI fallback** (when MCP unavailable):
|
**CLI fallback** (when MCP unavailable):
|
||||||
|
|
||||||
```
|
```
|
||||||
Bash("ccw team log --team ultra-analyze --from synthesizer --to coordinator --type synthesis_ready --summary \"[synthesizer] ...\" --ref <path> --json")
|
Bash("ccw team log --team <session-id> --from synthesizer --to coordinator --type synthesis_ready --summary \"[synthesizer] ...\" --ref <path> --json")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
Reference in New Issue
Block a user