mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 15:03:57 +08:00
feat: Add roles for issue resolution pipeline including planner, reviewer, integrator, and implementer
- Implemented `planner` role for solution design and task decomposition using issue-plan-agent. - Introduced `reviewer` role for solution review, technical feasibility validation, and risk assessment. - Created `integrator` role for queue formation and conflict detection using issue-queue-agent. - Added `implementer` role for code implementation and test verification via code-developer. - Defined message types and role boundaries for each role to ensure clear responsibilities. - Established a team configuration file to manage roles, pipelines, and collaboration patterns for the issue processing pipeline.
This commit is contained in:
@@ -1,41 +1,337 @@
|
||||
# Phase 4: Conflict Resolution (Conditional)
|
||||
|
||||
Detect and resolve conflicts when conflict risk is medium or high.
|
||||
Detect and resolve conflicts with CLI analysis. This phase is **conditional** - only executes when `conflict_risk >= medium`.
|
||||
|
||||
## Objective
|
||||
|
||||
- Execute conflict detection and resolution only when conflictRisk ≥ medium
|
||||
- Generate conflict-resolution.json with resolution strategies
|
||||
- Skip directly to Phase 5 if conflictRisk is none/low
|
||||
- Detect conflicts between planned changes and existing codebase
|
||||
- Detect module scenario uniqueness (functional overlaps)
|
||||
- Present conflicts to user with resolution strategies
|
||||
- Apply selected resolution strategies
|
||||
- Update planning-notes.md with conflict decisions
|
||||
|
||||
## Trigger Condition
|
||||
|
||||
**Only execute when**: `context-package.json` indicates `conflict_risk` is "medium" or "high"
|
||||
Only execute when context-package.json indicates `conflict_risk` is "medium" or "high".
|
||||
If `conflict_risk` is "none" or "low", skip directly to Phase 5.
|
||||
|
||||
**Skip Behavior**: If conflict_risk is "none" or "low", skip directly to Phase 5. Display: "No significant conflicts detected, proceeding to TDD task generation"
|
||||
## Conflict Categories
|
||||
|
||||
| Category | Description |
|
||||
|----------|-------------|
|
||||
| **Architecture** | Incompatible design patterns, module structure changes |
|
||||
| **API** | Breaking contract changes, signature modifications |
|
||||
| **Data Model** | Schema modifications, type breaking changes |
|
||||
| **Dependency** | Version incompatibilities, setup conflicts |
|
||||
| **ModuleOverlap** | Functional overlap, scenario boundary ambiguity, duplicate responsibility |
|
||||
|
||||
## Execution
|
||||
|
||||
### Step 4.1: Execute Conflict Resolution
|
||||
### Step 4.1: Validation
|
||||
|
||||
```javascript
|
||||
Skill(skill="workflow:tools:conflict-resolution", args="--session [sessionId] --context [contextPath]")
|
||||
// 1. Verify session directory exists
|
||||
const sessionDir = `.workflow/active/${sessionId}`;
|
||||
if (!file_exists(sessionDir)) {
|
||||
throw new Error(`Session directory not found: ${sessionDir}`);
|
||||
}
|
||||
|
||||
// 2. Load context-package.json
|
||||
const contextPackage = JSON.parse(Read(contextPath));
|
||||
|
||||
// 3. Check conflict_risk (skip if none/low)
|
||||
const conflictRisk = contextPackage.conflict_detection?.risk_level || 'low';
|
||||
if (conflictRisk === 'none' || conflictRisk === 'low') {
|
||||
console.log("No significant conflicts detected, proceeding to TDD task generation");
|
||||
// Skip directly to Phase 5
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
**Input**:
|
||||
- sessionId from Phase 1
|
||||
- contextPath from Phase 2
|
||||
- conflict_risk from context-package.json
|
||||
### Step 4.2: CLI-Powered Conflict Analysis
|
||||
|
||||
### Step 4.2: Parse Output
|
||||
**Agent Delegation**:
|
||||
|
||||
- Extract: Execution status (success/skipped/failed)
|
||||
- Verify: conflict-resolution.json file path (if executed)
|
||||
```javascript
|
||||
Task(subagent_type="cli-execution-agent", run_in_background=false, prompt=`
|
||||
## Context
|
||||
- Session: ${sessionId}
|
||||
- Risk: ${conflictRisk}
|
||||
- Files: ${existing_files_list}
|
||||
|
||||
**Validation**:
|
||||
- File `.workflow/active/[sessionId]/.process/conflict-resolution.json` exists (if executed)
|
||||
## Exploration Context (from context-package.exploration_results)
|
||||
- Exploration Count: ${contextPackage.exploration_results?.exploration_count || 0}
|
||||
- Angles Analyzed: ${JSON.stringify(contextPackage.exploration_results?.angles || [])}
|
||||
- Pre-identified Conflict Indicators: ${JSON.stringify(contextPackage.exploration_results?.aggregated_insights?.conflict_indicators || [])}
|
||||
- Critical Files: ${JSON.stringify(contextPackage.exploration_results?.aggregated_insights?.critical_files?.map(f => f.path) || [])}
|
||||
- All Patterns: ${JSON.stringify(contextPackage.exploration_results?.aggregated_insights?.all_patterns || [])}
|
||||
- All Integration Points: ${JSON.stringify(contextPackage.exploration_results?.aggregated_insights?.all_integration_points || [])}
|
||||
|
||||
### TodoWrite Update (Phase 4 Skill executed - tasks attached, if conflict_risk ≥ medium)
|
||||
## Analysis Steps
|
||||
|
||||
### 0. Load Output Schema (MANDATORY)
|
||||
Execute: cat ~/.ccw/workflows/cli-templates/schemas/conflict-resolution-schema.json
|
||||
|
||||
### 1. Load Context
|
||||
- Read existing files from conflict_detection.existing_files
|
||||
- Load plan from .workflow/active/${sessionId}/.process/context-package.json
|
||||
- Load exploration_results and use aggregated_insights for enhanced analysis
|
||||
- Extract role analyses and requirements
|
||||
|
||||
### 2. Execute CLI Analysis (Enhanced with Exploration + Scenario Uniqueness)
|
||||
|
||||
Primary (Gemini):
|
||||
ccw cli -p "
|
||||
PURPOSE: Detect conflicts between plan and codebase, using exploration insights
|
||||
TASK:
|
||||
* Review pre-identified conflict_indicators from exploration results
|
||||
* Compare architectures (use exploration key_patterns)
|
||||
* Identify breaking API changes
|
||||
* Detect data model incompatibilities
|
||||
* Assess dependency conflicts
|
||||
* Analyze module scenario uniqueness
|
||||
- Use exploration integration_points for precise locations
|
||||
- Cross-validate with exploration critical_files
|
||||
- Generate clarification questions for boundary definition
|
||||
MODE: analysis
|
||||
CONTEXT: @**/*.ts @**/*.js @**/*.tsx @**/*.jsx @.workflow/active/${sessionId}/**/*
|
||||
EXPECTED: Conflict list with severity ratings, including:
|
||||
- Validation of exploration conflict_indicators
|
||||
- ModuleOverlap conflicts with overlap_analysis
|
||||
- Targeted clarification questions
|
||||
CONSTRAINTS: Focus on breaking changes, migration needs, and functional overlaps | Prioritize exploration-identified conflicts | analysis=READ-ONLY
|
||||
" --tool gemini --mode analysis --rule analysis-code-patterns --cd {project_root}
|
||||
|
||||
Fallback: Qwen (same prompt) -> Claude (manual analysis)
|
||||
|
||||
### 3. Generate Strategies (2-4 per conflict)
|
||||
|
||||
Template per conflict:
|
||||
- Severity: Critical/High/Medium
|
||||
- Category: Architecture/API/Data/Dependency/ModuleOverlap
|
||||
- Affected files + impact
|
||||
- For ModuleOverlap: Include overlap_analysis with existing modules and scenarios
|
||||
- Options with pros/cons, effort, risk
|
||||
- For ModuleOverlap strategies: Add clarification_needed questions for boundary definition
|
||||
- Recommended strategy + rationale
|
||||
|
||||
### 4. Return Structured Conflict Data
|
||||
|
||||
Output to conflict-resolution.json (generated in Phase 4)
|
||||
|
||||
**Schema Reference**: Execute cat ~/.ccw/workflows/cli-templates/schemas/conflict-resolution-schema.json to get full schema
|
||||
|
||||
Return JSON following the schema. Key requirements:
|
||||
- Minimum 2 strategies per conflict, max 4
|
||||
- All text in Chinese for user-facing fields (brief, name, pros, cons, modification_suggestions)
|
||||
- modifications.old_content: 20-100 chars for unique Edit tool matching
|
||||
- modifications.new_content: preserves markdown formatting
|
||||
- modification_suggestions: 2-5 actionable suggestions for custom handling
|
||||
|
||||
### 5. Planning Notes Record (REQUIRED)
|
||||
After analysis complete, append to planning-notes.md:
|
||||
|
||||
**File**: .workflow/active/${sessionId}/planning-notes.md
|
||||
**Location**: Under "## Conflict Decisions (Phase 3)" section
|
||||
**Format**:
|
||||
### [Conflict-Resolution Agent] YYYY-MM-DD
|
||||
- **Note**: [Brief summary of conflict types, strategies, key decisions]
|
||||
`)
|
||||
```
|
||||
|
||||
### Step 4.3: Iterative User Interaction
|
||||
|
||||
```javascript
|
||||
const autoYes = workflowPreferences?.autoYes || false;
|
||||
|
||||
FOR each conflict:
|
||||
round = 0, clarified = false, userClarifications = []
|
||||
|
||||
WHILE (!clarified && round++ < 10):
|
||||
// 1. Display conflict info (text output for context)
|
||||
displayConflictSummary(conflict) // id, brief, severity, overlap_analysis if ModuleOverlap
|
||||
|
||||
// 2. Strategy selection
|
||||
if (autoYes) {
|
||||
console.log(`[autoYes] Auto-selecting recommended strategy`)
|
||||
selectedStrategy = conflict.strategies[conflict.recommended || 0]
|
||||
clarified = true // Skip clarification loop
|
||||
} else {
|
||||
AskUserQuestion({
|
||||
questions: [{
|
||||
question: formatStrategiesForDisplay(conflict.strategies),
|
||||
header: "Strategy",
|
||||
multiSelect: false,
|
||||
options: [
|
||||
...conflict.strategies.map((s, i) => ({
|
||||
label: `${s.name}${i === conflict.recommended ? ' (Recommended)' : ''}`,
|
||||
description: `${s.complexity} complexity | ${s.risk} risk${s.clarification_needed?.length ? ' | Needs clarification' : ''}`
|
||||
})),
|
||||
{ label: "Custom modification", description: `Suggestions: ${conflict.modification_suggestions?.slice(0,2).join('; ')}` }
|
||||
]
|
||||
}]
|
||||
})
|
||||
|
||||
// 3. Handle selection
|
||||
if (userChoice === "Custom modification") {
|
||||
customConflicts.push({ id, brief, category, suggestions, overlap_analysis })
|
||||
break
|
||||
}
|
||||
|
||||
selectedStrategy = findStrategyByName(userChoice)
|
||||
}
|
||||
|
||||
// 4. Clarification (if needed) - batched max 4 per call
|
||||
if (!autoYes && selectedStrategy.clarification_needed?.length > 0) {
|
||||
for (batch of chunk(selectedStrategy.clarification_needed, 4)) {
|
||||
AskUserQuestion({
|
||||
questions: batch.map((q, i) => ({
|
||||
question: q, header: `Clarify${i+1}`, multiSelect: false,
|
||||
options: [{ label: "Provide details", description: "Enter answer" }]
|
||||
}))
|
||||
})
|
||||
userClarifications.push(...collectAnswers(batch))
|
||||
}
|
||||
|
||||
// 5. Agent re-analysis
|
||||
reanalysisResult = Task({
|
||||
subagent_type: "cli-execution-agent",
|
||||
run_in_background: false,
|
||||
prompt: `Conflict: ${conflict.id}, Strategy: ${selectedStrategy.name}
|
||||
User Clarifications: ${JSON.stringify(userClarifications)}
|
||||
Output: { uniqueness_confirmed, rationale, updated_strategy, remaining_questions }`
|
||||
})
|
||||
|
||||
if (reanalysisResult.uniqueness_confirmed) {
|
||||
selectedStrategy = { ...reanalysisResult.updated_strategy, clarifications: userClarifications }
|
||||
clarified = true
|
||||
} else {
|
||||
selectedStrategy.clarification_needed = reanalysisResult.remaining_questions
|
||||
}
|
||||
} else {
|
||||
clarified = true
|
||||
}
|
||||
|
||||
if (clarified) resolvedConflicts.push({ conflict, strategy: selectedStrategy })
|
||||
END WHILE
|
||||
END FOR
|
||||
|
||||
selectedStrategies = resolvedConflicts.map(r => ({
|
||||
conflict_id: r.conflict.id, strategy: r.strategy, clarifications: r.strategy.clarifications || []
|
||||
}))
|
||||
```
|
||||
|
||||
### Step 4.4: Apply Modifications
|
||||
|
||||
```javascript
|
||||
// 1. Extract modifications from resolved strategies
|
||||
const modifications = [];
|
||||
selectedStrategies.forEach(item => {
|
||||
if (item.strategy && item.strategy.modifications) {
|
||||
modifications.push(...item.strategy.modifications.map(mod => ({
|
||||
...mod,
|
||||
conflict_id: item.conflict_id,
|
||||
clarifications: item.clarifications
|
||||
})));
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Applying ${modifications.length} modifications...`);
|
||||
|
||||
// 2. Apply each modification using Edit tool (with fallback to context-package.json)
|
||||
const appliedModifications = [];
|
||||
const failedModifications = [];
|
||||
const fallbackConstraints = []; // For files that don't exist
|
||||
|
||||
modifications.forEach((mod, idx) => {
|
||||
try {
|
||||
console.log(`[${idx + 1}/${modifications.length}] Modifying ${mod.file}...`);
|
||||
|
||||
// Check if target file exists (brainstorm files may not exist in lite workflow)
|
||||
if (!file_exists(mod.file)) {
|
||||
console.log(` File not found, writing to context-package.json as constraint`);
|
||||
fallbackConstraints.push({
|
||||
source: "conflict-resolution",
|
||||
conflict_id: mod.conflict_id,
|
||||
target_file: mod.file,
|
||||
section: mod.section,
|
||||
change_type: mod.change_type,
|
||||
content: mod.new_content,
|
||||
rationale: mod.rationale
|
||||
});
|
||||
return; // Skip to next modification
|
||||
}
|
||||
|
||||
if (mod.change_type === "update") {
|
||||
Edit({ file_path: mod.file, old_string: mod.old_content, new_string: mod.new_content });
|
||||
} else if (mod.change_type === "add") {
|
||||
const fileContent = Read(mod.file);
|
||||
const updated = insertContentAfterSection(fileContent, mod.section, mod.new_content);
|
||||
Write(mod.file, updated);
|
||||
} else if (mod.change_type === "remove") {
|
||||
Edit({ file_path: mod.file, old_string: mod.old_content, new_string: "" });
|
||||
}
|
||||
|
||||
appliedModifications.push(mod);
|
||||
console.log(` Success`);
|
||||
} catch (error) {
|
||||
console.log(` Failed: ${error.message}`);
|
||||
failedModifications.push({ ...mod, error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// 3. Generate conflict-resolution.json output file
|
||||
const resolutionOutput = {
|
||||
session_id: sessionId,
|
||||
resolved_at: new Date().toISOString(),
|
||||
summary: {
|
||||
total_conflicts: conflicts.length,
|
||||
resolved_with_strategy: selectedStrategies.length,
|
||||
custom_handling: customConflicts.length,
|
||||
fallback_constraints: fallbackConstraints.length
|
||||
},
|
||||
resolved_conflicts: selectedStrategies.map(s => ({
|
||||
conflict_id: s.conflict_id,
|
||||
strategy_name: s.strategy.name,
|
||||
strategy_approach: s.strategy.approach,
|
||||
clarifications: s.clarifications || [],
|
||||
modifications_applied: s.strategy.modifications?.filter(m =>
|
||||
appliedModifications.some(am => am.conflict_id === s.conflict_id)
|
||||
) || []
|
||||
})),
|
||||
custom_conflicts: customConflicts.map(c => ({
|
||||
id: c.id, brief: c.brief, category: c.category,
|
||||
suggestions: c.suggestions, overlap_analysis: c.overlap_analysis || null
|
||||
})),
|
||||
planning_constraints: fallbackConstraints,
|
||||
failed_modifications: failedModifications
|
||||
};
|
||||
|
||||
const resolutionPath = `.workflow/active/${sessionId}/.process/conflict-resolution.json`;
|
||||
Write(resolutionPath, JSON.stringify(resolutionOutput, null, 2));
|
||||
|
||||
// 4. Update context-package.json with resolution details
|
||||
const contextPkg = JSON.parse(Read(contextPath));
|
||||
contextPkg.conflict_detection.conflict_risk = "resolved";
|
||||
contextPkg.conflict_detection.resolution_file = resolutionPath;
|
||||
contextPkg.conflict_detection.resolved_conflicts = selectedStrategies.map(s => s.conflict_id);
|
||||
contextPkg.conflict_detection.custom_conflicts = customConflicts.map(c => c.id);
|
||||
contextPkg.conflict_detection.resolved_at = new Date().toISOString();
|
||||
Write(contextPath, JSON.stringify(contextPkg, null, 2));
|
||||
|
||||
// 5. Output custom conflict summary with overlap analysis (if any)
|
||||
if (customConflicts.length > 0) {
|
||||
customConflicts.forEach(conflict => {
|
||||
console.log(`[${conflict.category}] ${conflict.id}: ${conflict.brief}`);
|
||||
if (conflict.category === 'ModuleOverlap' && conflict.overlap_analysis) {
|
||||
console.log(`Overlap info: New module: ${conflict.overlap_analysis.new_module.name}`);
|
||||
}
|
||||
conflict.suggestions.forEach(s => console.log(` - ${s}`));
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### TodoWrite Update (Phase 4 in progress - tasks attached, if conflict_risk >= medium)
|
||||
|
||||
```json
|
||||
[
|
||||
@@ -43,18 +339,14 @@ Skill(skill="workflow:tools:conflict-resolution", args="--session [sessionId] --
|
||||
{"content": "Phase 2: Context Gathering", "status": "completed", "activeForm": "Executing context gathering"},
|
||||
{"content": "Phase 3: Test Coverage Analysis", "status": "completed", "activeForm": "Executing test coverage analysis"},
|
||||
{"content": "Phase 4: Conflict Resolution", "status": "in_progress", "activeForm": "Executing conflict resolution"},
|
||||
{"content": " → Detect conflicts with CLI analysis", "status": "in_progress", "activeForm": "Detecting conflicts"},
|
||||
{"content": " → Log and analyze detected conflicts", "status": "pending", "activeForm": "Analyzing conflicts"},
|
||||
{"content": " → Apply resolution strategies", "status": "pending", "activeForm": "Applying resolution strategies"},
|
||||
{"content": " -> Detect conflicts with CLI analysis", "status": "in_progress", "activeForm": "Detecting conflicts"},
|
||||
{"content": " -> Present conflicts to user", "status": "pending", "activeForm": "Presenting conflicts"},
|
||||
{"content": " -> Apply resolution strategies", "status": "pending", "activeForm": "Applying resolution strategies"},
|
||||
{"content": "Phase 5: TDD Task Generation", "status": "pending", "activeForm": "Executing TDD task generation"},
|
||||
{"content": "Phase 6: TDD Structure Validation", "status": "pending", "activeForm": "Validating TDD structure"}
|
||||
]
|
||||
```
|
||||
|
||||
**Note**: Skill execute **attaches** conflict-resolution's 3 tasks. Orchestrator **executes** these tasks.
|
||||
|
||||
**Next Action**: Tasks attached → **Execute Phase 4.1-4.3** sequentially
|
||||
|
||||
### TodoWrite Update (Phase 4 completed - tasks collapsed)
|
||||
|
||||
```json
|
||||
@@ -68,26 +360,65 @@ Skill(skill="workflow:tools:conflict-resolution", args="--session [sessionId] --
|
||||
]
|
||||
```
|
||||
|
||||
**Note**: Phase 4 tasks completed and collapsed to summary.
|
||||
### Step 4.5: Update Planning Notes
|
||||
|
||||
**After Phase 4**: Return to user showing conflict resolution results and selected strategies, then auto-continue to Phase 5
|
||||
After conflict resolution completes (if executed), update planning-notes.md:
|
||||
|
||||
### Memory State Check
|
||||
```javascript
|
||||
if (conflictRisk === 'medium' || conflictRisk === 'high') {
|
||||
const conflictResPath = `.workflow/active/${sessionId}/.process/conflict-resolution.json`;
|
||||
|
||||
if (file_exists(conflictResPath)) {
|
||||
const conflictRes = JSON.parse(Read(conflictResPath));
|
||||
const resolved = conflictRes.resolved_conflicts || [];
|
||||
const modifiedArtifacts = conflictRes.modified_artifacts || [];
|
||||
const planningConstraints = conflictRes.planning_constraints || [];
|
||||
|
||||
// Update Phase 4 section
|
||||
Edit(planningNotesPath, {
|
||||
old: '## Conflict Decisions (Phase 4)\n(To be filled if conflicts detected)',
|
||||
new: `## Conflict Decisions (Phase 4)
|
||||
|
||||
- **RESOLVED**: ${resolved.map(r => `${r.type} -> ${r.strategy}`).join('; ') || 'None'}
|
||||
- **MODIFIED_ARTIFACTS**: ${modifiedArtifacts.join(', ') || 'None'}
|
||||
- **CONSTRAINTS**: ${planningConstraints.join('; ') || 'None'}`
|
||||
})
|
||||
|
||||
// Append Phase 4 constraints to consolidated list
|
||||
if (planningConstraints.length > 0) {
|
||||
const currentNotes = Read(planningNotesPath);
|
||||
const constraintCount = (currentNotes.match(/^\d+\./gm) || []).length;
|
||||
|
||||
Edit(planningNotesPath, {
|
||||
old: '## Consolidated Constraints (Phase 5 Input)',
|
||||
new: `## Consolidated Constraints (Phase 5 Input)
|
||||
${planningConstraints.map((c, i) => `${constraintCount + i + 1}. [Conflict] ${c}`).join('\n')}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Auto-Continue**: Return to user showing conflict resolution results and selected strategies, then auto-continue.
|
||||
|
||||
**Auto Mode**: When `workflowPreferences.autoYes` is true, conflict-resolution automatically applies recommended resolution strategies without user confirmation.
|
||||
|
||||
### Step 4.6: Memory State Check
|
||||
|
||||
Evaluate current context window usage and memory state:
|
||||
|
||||
After Phase 4, evaluate current context window usage and memory state:
|
||||
- If memory usage is high (>110K tokens or approaching context limits):
|
||||
|
||||
```javascript
|
||||
Skill(skill="compact")
|
||||
```
|
||||
```javascript
|
||||
Skill(skill="compact")
|
||||
```
|
||||
|
||||
- This optimizes memory before proceeding to Phase 5
|
||||
- Memory compaction is particularly important after analysis phase which may generate extensive documentation
|
||||
- Ensures optimal performance and prevents context overflow
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `.workflow/active/[sessionId]/.process/conflict-resolution.json` (if executed)
|
||||
- **File**: `conflict-resolution.json` (if conflicts resolved)
|
||||
- **TodoWrite**: Mark Phase 4 completed, Phase 5 in_progress
|
||||
|
||||
## Next Phase
|
||||
|
||||
Reference in New Issue
Block a user