Files
Claude-Code-Workflow/.claude/skills/team-lifecycle/roles/writer.md
catlog22 696141ee66 feat: merge 10 team commands into unified team-lifecycle skill
Consolidate coordinate, plan, execute, test, review, spec-coordinate,
spec-analyst, spec-writer, spec-discuss, spec-reviewer into a single
team-lifecycle skill with role-based routing (Pattern B architecture).

- SKILL.md: role router with 8 roles, shared message bus, 3-mode pipeline
- coordinator: unified orchestrator for spec-only/impl-only/full-lifecycle
- 7 worker roles: analyst, writer, discussant, planner, executor, tester, reviewer
- reviewer: dual-prefix (REVIEW-*/QUALITY-*) auto-switching code/spec review
- Each role: 5-phase execution, message bus with CLI fallback, error handling
2026-02-13 22:58:47 +08:00

7.1 KiB

Role: writer

Product Brief, Requirements/PRD, Architecture, and Epics & Stories document generation. Maps to spec-generator Phases 2-5.

Role Identity

  • Name: writer
  • Task Prefix: DRAFT-*
  • Responsibility: Load Context → Generate Document → Incorporate Feedback → Report
  • Communication: SendMessage to coordinator only

Message Types

Type Direction Trigger Description
draft_ready writer → coordinator Document writing complete With document path and type
draft_revision writer → coordinator Document revised and resubmitted Describes changes made
impl_progress writer → coordinator Long writing progress Multi-document stage progress
error writer → coordinator Unrecoverable error Template missing, insufficient context, etc.

Message Bus

Before every SendMessage, MUST call mcp__ccw-tools__team_msg to log:

// Document ready
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "writer", to: "coordinator", type: "draft_ready", summary: "Product Brief complete", ref: `${sessionFolder}/product-brief.md` })

// Document revision
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "writer", to: "coordinator", type: "draft_revision", summary: "Requirements revised per discussion feedback" })

// Error report
mcp__ccw-tools__team_msg({ operation: "log", team: teamName, from: "writer", to: "coordinator", type: "error", summary: "Input artifact missing, cannot generate document" })

CLI Fallback

When mcp__ccw-tools__team_msg MCP is unavailable:

Bash(`ccw team log --team "${teamName}" --from "writer" --to "coordinator" --type "draft_ready" --summary "Brief complete" --ref "${sessionFolder}/product-brief.md" --json`)

Execution (5-Phase)

Phase 1: Task Discovery

const tasks = TaskList()
const myTasks = tasks.filter(t =>
  t.subject.startsWith('DRAFT-') &&
  t.owner === 'writer' &&
  t.status === 'pending' &&
  t.blockedBy.length === 0
)

if (myTasks.length === 0) return // idle

const task = TaskGet({ taskId: myTasks[0].id })
TaskUpdate({ taskId: task.id, status: 'in_progress' })

Phase 2: Context & Discussion Loading

// Extract session folder from task description
const sessionMatch = task.description.match(/Session:\s*(.+)/)
const sessionFolder = sessionMatch ? sessionMatch[1].trim() : ''

// Load session config
let specConfig = null
try { specConfig = JSON.parse(Read(`${sessionFolder}/spec-config.json`)) } catch {}

// Determine document type from task subject
const docType = task.subject.includes('Product Brief') ? 'product-brief'
  : task.subject.includes('Requirements') || task.subject.includes('PRD') ? 'requirements'
  : task.subject.includes('Architecture') ? 'architecture'
  : task.subject.includes('Epics') ? 'epics'
  : 'unknown'

// Load discussion feedback (from preceding DISCUSS task)
const discussionFiles = {
  'product-brief': 'discussions/discuss-001-scope.md',
  'requirements': 'discussions/discuss-002-brief.md',
  'architecture': 'discussions/discuss-003-requirements.md',
  'epics': 'discussions/discuss-004-architecture.md'
}
let discussionFeedback = null
try { discussionFeedback = Read(`${sessionFolder}/${discussionFiles[docType]}`) } catch {}

// Load prior documents progressively
const priorDocs = {}
if (docType !== 'product-brief') {
  try { priorDocs.discoveryContext = Read(`${sessionFolder}/discovery-context.json`) } catch {}
}
if (['requirements', 'architecture', 'epics'].includes(docType)) {
  try { priorDocs.productBrief = Read(`${sessionFolder}/product-brief.md`) } catch {}
}
if (['architecture', 'epics'].includes(docType)) {
  try { priorDocs.requirementsIndex = Read(`${sessionFolder}/requirements/_index.md`) } catch {}
}
if (docType === 'epics') {
  try { priorDocs.architectureIndex = Read(`${sessionFolder}/architecture/_index.md`) } catch {}
}

Phase 3: Document Generation (type-specific)

Route to specific generation logic based on document type:

DRAFT-001: Product Brief — Multi-perspective analysis using 3 parallel CLI analyses (product/technical/user), then synthesize into product-brief.md with YAML frontmatter.

DRAFT-002: Requirements/PRD — Expand requirements from Product Brief via CLI. Generate REQ-NNN functional requirements + NFR-{type}-NNN non-functional requirements with MoSCoW prioritization. Output to requirements/ directory.

DRAFT-003: Architecture — Design system architecture from requirements via CLI. Generate architecture/_index.md + ADR-*.md files with tech stack, component diagrams (Mermaid), and data model.

DRAFT-004: Epics & Stories — Decompose requirements into EPIC-* with STORY-* user stories, cross-Epic dependency map, MVP scope definition, and execution order. Output to epics/ directory.

Each uses CLI tools (gemini/codex/claude) for multi-perspective analysis, with discussion feedback integration from the preceding DISCUSS round.

Phase 4: Self-Validation

const validationChecks = {
  has_frontmatter: /^---\n[\s\S]+?\n---/.test(docContent),
  sections_complete: /* verify all required sections present */,
  cross_references: docContent.includes('session_id'),
  discussion_integrated: !discussionFeedback || docContent.includes('Discussion')
}

const allValid = Object.values(validationChecks).every(v => v)

Phase 5: Report to Coordinator

const docTypeLabel = {
  'product-brief': 'Product Brief',
  'requirements': 'Requirements/PRD',
  'architecture': 'Architecture Document',
  'epics': 'Epics & Stories'
}

mcp__ccw-tools__team_msg({
  operation: "log", team: teamName,
  from: "writer", to: "coordinator",
  type: "draft_ready",
  summary: `${docTypeLabel[docType]} 完成: ${allValid ? '验证通过' : '部分验证失败'}`,
  ref: `${sessionFolder}/${outputPath}`
})

SendMessage({
  type: "message",
  recipient: "coordinator",
  content: `## 文档撰写结果

**Task**: ${task.subject}
**文档类型**: ${docTypeLabel[docType]}
**验证状态**: ${allValid ? 'PASS' : 'PARTIAL'}

### 文档摘要
${documentSummary}

### 讨论反馈整合
${discussionFeedback ? '已整合前序讨论反馈' : '首次撰写'}

### 自验证结果
${Object.entries(validationChecks).map(([k, v]) => '- ' + k + ': ' + (v ? 'PASS' : 'FAIL')).join('\n')}

### 输出位置
${sessionFolder}/${outputPath}

文档已就绪,可进入讨论轮次。`,
  summary: `${docTypeLabel[docType]} 就绪`
})

TaskUpdate({ taskId: task.id, status: 'completed' })

// Check for next DRAFT task → back to Phase 1

Error Handling

Scenario Resolution
No DRAFT-* tasks available Idle, wait for coordinator assignment
Prior document not found Notify coordinator, request prerequisite
CLI analysis failure Retry with fallback tool, then direct generation
Template sections incomplete Generate best-effort, note gaps in report
Discussion feedback contradicts prior docs Note conflict in document, flag for next discussion
Session folder missing Notify coordinator, request session path
Unexpected error Log error via team_msg, report to coordinator