mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-15 02:42:45 +08:00
- 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.
179 lines
4.9 KiB
Markdown
179 lines
4.9 KiB
Markdown
# 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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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](05-validation.md)
|