Files
Claude-Code-Workflow/.claude/skills/team-skill-designer/phases/04-integration-verification.md
catlog22 a512564b5a Add integration verification and validation phases, role templates, and static graph tests
- Implement Phase 4: Integration Verification to ensure skill package consistency.
- Implement Phase 5: Validation to verify quality and deliver the final skill package.
- Create role-template.md for generating per-role execution detail files.
- Create skill-router-template.md for generating SKILL.md with role-based routing.
- Add tests for static graph relationship writing during index build in test_static_graph_integration.py.
2026-02-13 12:35:31 +08:00

4.9 KiB

Phase 4: Integration Verification

Verify the generated skill package is internally consistent.

Objective

  • Verify SKILL.md role router references match actual role files
  • Verify task prefixes are unique across all roles
  • Verify message types are consistent
  • Verify coordinator spawn template uses correct skill invocation
  • Generate integration-report.json

Input

  • Dependency: {workDir}/preview/ directory (Phase 3)
  • Reference: team-config.json (Phase 1)

Execution Steps

Step 1: Load Generated Files

const config = JSON.parse(Read(`${workDir}/team-config.json`))
const previewDir = `${workDir}/preview`
const skillMd = Read(`${previewDir}/SKILL.md`)

const roleFiles = {}
for (const role of config.roles) {
  try {
    roleFiles[role.name] = Read(`${previewDir}/roles/${role.name}.md`)
  } catch {
    roleFiles[role.name] = null
  }
}

Step 2: Role Router Consistency

const routerChecks = config.roles.map(role => {
  const hasRouterEntry = skillMd.includes(`"${role.name}"`)
  const hasRoleFile = roleFiles[role.name] !== null
  const hasRoleLink = skillMd.includes(`roles/${role.name}.md`)

  return {
    role: role.name,
    router_entry: hasRouterEntry,
    file_exists: hasRoleFile,
    link_valid: hasRoleLink,
    status: (hasRouterEntry && hasRoleFile && hasRoleLink) ? 'PASS' : 'FAIL'
  }
})

Step 3: Task Prefix Uniqueness

const prefixes = config.worker_roles.map(r => r.task_prefix)
const uniquePrefixes = [...new Set(prefixes)]
const prefixCheck = {
  prefixes: prefixes,
  unique: uniquePrefixes,
  duplicates: prefixes.filter((p, i) => prefixes.indexOf(p) !== i),
  status: prefixes.length === uniquePrefixes.length ? 'PASS' : 'FAIL'
}

Step 4: Message Type Consistency

const msgChecks = config.worker_roles.map(role => {
  const roleFile = roleFiles[role.name] || ''
  const typesInConfig = role.message_types.map(mt => mt.type)
  const typesInFile = typesInConfig.filter(t => roleFile.includes(t))

  return {
    role: role.name,
    configured: typesInConfig,
    present_in_file: typesInFile,
    missing: typesInConfig.filter(t => !typesInFile.includes(t)),
    status: typesInFile.length === typesInConfig.length ? 'PASS' : 'WARN'
  }
})

Step 5: Spawn Template Verification

const spawnChecks = config.worker_roles.map(role => {
  const hasSpawn = skillMd.includes(`name: "${role.name}"`)
  const hasSkillCall = skillMd.includes(`Skill(skill="${config.skill_name}", args="--role=${role.name}")`)
  const hasTaskPrefix = skillMd.includes(`${role.task_prefix}-*`)

  return {
    role: role.name,
    spawn_present: hasSpawn,
    skill_call_correct: hasSkillCall,
    prefix_in_prompt: hasTaskPrefix,
    status: (hasSpawn && hasSkillCall && hasTaskPrefix) ? 'PASS' : 'FAIL'
  }
})

Step 6: Role File Pattern Compliance

const patternChecks = Object.entries(roleFiles).map(([name, content]) => {
  if (!content) return { role: name, status: 'MISSING' }

  const checks = {
    has_role_identity: /## Role Identity/.test(content),
    has_5_phases: /Phase 1/.test(content) && /Phase 5/.test(content),
    has_task_lifecycle: /TaskList/.test(content) && /TaskGet/.test(content) && /TaskUpdate/.test(content),
    has_message_bus: /team_msg/.test(content),
    has_send_message: /SendMessage/.test(content),
    has_error_handling: /## Error Handling/.test(content)
  }

  const passCount = Object.values(checks).filter(Boolean).length
  return {
    role: name,
    checks: checks,
    pass_count: passCount,
    total: Object.keys(checks).length,
    status: passCount === Object.keys(checks).length ? 'PASS' : 'PARTIAL'
  }
})

Step 7: Generate Report

const overallStatus = [
  ...routerChecks.map(c => c.status),
  prefixCheck.status,
  ...spawnChecks.map(c => c.status),
  ...patternChecks.map(c => c.status)
].every(s => s === 'PASS') ? 'PASS' : 'NEEDS_ATTENTION'

const report = {
  team_name: config.team_name,
  skill_name: config.skill_name,
  checks: {
    router_consistency: routerChecks,
    prefix_uniqueness: prefixCheck,
    message_types: msgChecks,
    spawn_template: spawnChecks,
    pattern_compliance: patternChecks
  },
  overall: overallStatus,
  file_count: {
    skill_md: 1,
    role_files: Object.keys(roleFiles).length,
    total: 1 + Object.keys(roleFiles).length + 1  // SKILL.md + roles + config
  }
}

Write(`${workDir}/integration-report.json`, JSON.stringify(report, null, 2))

Output

  • File: integration-report.json
  • Format: JSON
  • Location: {workDir}/integration-report.json

Quality Checklist

  • Every role in config has a router entry in SKILL.md
  • Every role has a file in roles/
  • Task prefixes are unique
  • Spawn template uses correct Skill(skill="...", args="--role=...")
  • All role files have 5-phase structure
  • All role files have message bus integration

Next Phase

-> Phase 5: Validation