Files
Claude-Code-Workflow/.claude/skills/skill-tuning/phases/actions/action-propose-fixes.md
catlog22 633d918da1 Add quality gates and tuning strategies documentation
- Introduced quality gates specification for skill tuning, detailing quality dimensions, scoring, and gate definitions.
- Added comprehensive tuning strategies for various issue categories, including context explosion, long-tail forgetting, data flow, and agent coordination.
- Created templates for diagnosis reports and fix proposals to standardize documentation and reporting processes.
2026-01-14 12:59:13 +08:00

11 KiB

Action: Propose Fixes

Generate fix proposals for identified issues with implementation strategies.

Purpose

  • Create fix strategies for each issue
  • Generate implementation plans
  • Estimate risk levels
  • Allow user to select fixes to apply

Preconditions

  • state.status === 'running'
  • state.issues.length > 0
  • action-generate-report completed

Fix Strategy Catalog

Context Explosion Fixes

Strategy Description Risk
context_summarization Add summarizer agent between phases low
sliding_window Keep only last N turns in context low
structured_state Replace text context with JSON state medium
path_reference Pass file paths instead of content low

Memory Loss Fixes

Strategy Description Risk
constraint_injection Add constraints to each phase prompt low
checkpoint_restore Save state at milestones low
goal_embedding Track goal similarity throughout medium
state_constraints_field Add constraints field to state schema low

Data Flow Fixes

Strategy Description Risk
state_centralization Single state.json for all data medium
schema_enforcement Add Zod validation low
field_normalization Normalize field names low
transactional_updates Atomic state updates medium

Agent Coordination Fixes

Strategy Description Risk
error_wrapping Add try-catch to all Task calls low
result_validation Validate agent returns low
orchestrator_refactor Centralize agent coordination high
flatten_nesting Remove nested agent calls medium

Execution

async function execute(state, workDir) {
  console.log('Generating fix proposals...');

  const issues = state.issues;
  const fixes = [];

  // Group issues by type for batch fixes
  const issuesByType = {
    context_explosion: issues.filter(i => i.type === 'context_explosion'),
    memory_loss: issues.filter(i => i.type === 'memory_loss'),
    dataflow_break: issues.filter(i => i.type === 'dataflow_break'),
    agent_failure: issues.filter(i => i.type === 'agent_failure')
  };

  // Generate fixes for context explosion
  if (issuesByType.context_explosion.length > 0) {
    const ctxIssues = issuesByType.context_explosion;

    if (ctxIssues.some(i => i.description.includes('history accumulation'))) {
      fixes.push({
        id: `FIX-${fixes.length + 1}`,
        issue_ids: ctxIssues.filter(i => i.description.includes('history')).map(i => i.id),
        strategy: 'sliding_window',
        description: 'Implement sliding window for conversation history',
        rationale: 'Prevents unbounded context growth by keeping only recent turns',
        changes: [{
          file: 'phases/orchestrator.md',
          action: 'modify',
          diff: `+ const MAX_HISTORY = 5;
+ state.history = state.history.slice(-MAX_HISTORY);`
        }],
        risk: 'low',
        estimated_impact: 'Reduces token usage by ~50%',
        verification_steps: ['Run skill with 10+ iterations', 'Verify context size stable']
      });
    }

    if (ctxIssues.some(i => i.description.includes('full content'))) {
      fixes.push({
        id: `FIX-${fixes.length + 1}`,
        issue_ids: ctxIssues.filter(i => i.description.includes('content')).map(i => i.id),
        strategy: 'path_reference',
        description: 'Pass file paths instead of full content',
        rationale: 'Agents can read files when needed, reducing prompt size',
        changes: [{
          file: 'phases/*.md',
          action: 'modify',
          diff: `- prompt: \${content}
+ prompt: Read file at: \${filePath}`
        }],
        risk: 'low',
        estimated_impact: 'Significant token reduction',
        verification_steps: ['Verify agents can still access needed content']
      });
    }
  }

  // Generate fixes for memory loss
  if (issuesByType.memory_loss.length > 0) {
    const memIssues = issuesByType.memory_loss;

    if (memIssues.some(i => i.description.includes('constraint'))) {
      fixes.push({
        id: `FIX-${fixes.length + 1}`,
        issue_ids: memIssues.filter(i => i.description.includes('constraint')).map(i => i.id),
        strategy: 'constraint_injection',
        description: 'Add constraint injection to all phases',
        rationale: 'Ensures original requirements are visible in every phase',
        changes: [{
          file: 'phases/*.md',
          action: 'modify',
          diff: `+ [CONSTRAINTS]
+ Original requirements from state.original_requirements:
+ \${JSON.stringify(state.original_requirements)}`
        }],
        risk: 'low',
        estimated_impact: 'Improves constraint adherence',
        verification_steps: ['Run skill with specific constraints', 'Verify output matches']
      });
    }

    if (memIssues.some(i => i.description.includes('State schema'))) {
      fixes.push({
        id: `FIX-${fixes.length + 1}`,
        issue_ids: memIssues.filter(i => i.description.includes('schema')).map(i => i.id),
        strategy: 'state_constraints_field',
        description: 'Add original_requirements field to state schema',
        rationale: 'Preserves original intent throughout execution',
        changes: [{
          file: 'phases/state-schema.md',
          action: 'modify',
          diff: `+ original_requirements: string[];  // User's original constraints
+ goal_summary: string;              // One-line goal statement`
        }],
        risk: 'low',
        estimated_impact: 'Enables constraint tracking',
        verification_steps: ['Verify state includes requirements after init']
      });
    }
  }

  // Generate fixes for data flow
  if (issuesByType.dataflow_break.length > 0) {
    const dfIssues = issuesByType.dataflow_break;

    if (dfIssues.some(i => i.description.includes('multiple locations'))) {
      fixes.push({
        id: `FIX-${fixes.length + 1}`,
        issue_ids: dfIssues.filter(i => i.description.includes('location')).map(i => i.id),
        strategy: 'state_centralization',
        description: 'Centralize all state to single state.json',
        rationale: 'Single source of truth prevents inconsistencies',
        changes: [{
          file: 'phases/*.md',
          action: 'modify',
          diff: `- Write(\`\${workDir}/config.json\`, ...)
+ updateState({ config: ... })  // Use state manager`
        }],
        risk: 'medium',
        estimated_impact: 'Eliminates state fragmentation',
        verification_steps: ['Verify all reads come from state.json', 'Test state persistence']
      });
    }

    if (dfIssues.some(i => i.description.includes('validation'))) {
      fixes.push({
        id: `FIX-${fixes.length + 1}`,
        issue_ids: dfIssues.filter(i => i.description.includes('validation')).map(i => i.id),
        strategy: 'schema_enforcement',
        description: 'Add Zod schema validation',
        rationale: 'Runtime validation catches schema violations',
        changes: [{
          file: 'phases/state-schema.md',
          action: 'modify',
          diff: `+ import { z } from 'zod';
+ const StateSchema = z.object({...});
+ function validateState(s) { return StateSchema.parse(s); }`
        }],
        risk: 'low',
        estimated_impact: 'Catches invalid state early',
        verification_steps: ['Test with invalid state input', 'Verify error thrown']
      });
    }
  }

  // Generate fixes for agent coordination
  if (issuesByType.agent_failure.length > 0) {
    const agentIssues = issuesByType.agent_failure;

    if (agentIssues.some(i => i.description.includes('error handling'))) {
      fixes.push({
        id: `FIX-${fixes.length + 1}`,
        issue_ids: agentIssues.filter(i => i.description.includes('error')).map(i => i.id),
        strategy: 'error_wrapping',
        description: 'Wrap all Task calls in try-catch',
        rationale: 'Prevents cascading failures from agent errors',
        changes: [{
          file: 'phases/*.md',
          action: 'modify',
          diff: `+ try {
    const result = await Task({...});
+   if (!result) throw new Error('Empty result');
+ } catch (e) {
+   updateState({ errors: [...errors, e.message], error_count: error_count + 1 });
+ }`
        }],
        risk: 'low',
        estimated_impact: 'Improves error resilience',
        verification_steps: ['Simulate agent failure', 'Verify graceful handling']
      });
    }

    if (agentIssues.some(i => i.description.includes('nested'))) {
      fixes.push({
        id: `FIX-${fixes.length + 1}`,
        issue_ids: agentIssues.filter(i => i.description.includes('nested')).map(i => i.id),
        strategy: 'flatten_nesting',
        description: 'Flatten nested agent calls',
        rationale: 'Reduces complexity and context explosion',
        changes: [{
          file: 'phases/orchestrator.md',
          action: 'modify',
          diff: `// Instead of agent calling agent:
// Agent A returns {needs_agent_b: true}
// Orchestrator sees this and calls Agent B next`
        }],
        risk: 'medium',
        estimated_impact: 'Reduces nesting depth',
        verification_steps: ['Verify no nested Task calls', 'Test agent chaining via orchestrator']
      });
    }
  }

  // Write fix proposals
  Write(`${workDir}/fixes/fix-proposals.json`, JSON.stringify(fixes, null, 2));

  // Ask user to select fixes to apply
  const fixOptions = fixes.slice(0, 4).map(f => ({
    label: f.id,
    description: `[${f.risk.toUpperCase()} risk] ${f.description}`
  }));

  if (fixOptions.length > 0) {
    const selection = await AskUserQuestion({
      questions: [{
        question: 'Which fixes would you like to apply?',
        header: 'Fixes',
        multiSelect: true,
        options: fixOptions
      }]
    });

    const selectedFixIds = Array.isArray(selection['Fixes'])
      ? selection['Fixes']
      : [selection['Fixes']];

    return {
      stateUpdates: {
        proposed_fixes: fixes,
        pending_fixes: selectedFixIds.filter(id => id && fixes.some(f => f.id === id))
      },
      outputFiles: [`${workDir}/fixes/fix-proposals.json`],
      summary: `Generated ${fixes.length} fix proposals, ${selectedFixIds.length} selected for application`
    };
  }

  return {
    stateUpdates: {
      proposed_fixes: fixes,
      pending_fixes: []
    },
    outputFiles: [`${workDir}/fixes/fix-proposals.json`],
    summary: `Generated ${fixes.length} fix proposals (none selected)`
  };
}

State Updates

return {
  stateUpdates: {
    proposed_fixes: [...fixes],
    pending_fixes: [...selectedFixIds]
  }
};

Error Handling

Error Type Recovery
No issues to fix Skip to action-complete
User cancels selection Set pending_fixes to empty

Next Actions

  • If pending_fixes.length > 0: action-apply-fix
  • If pending_fixes.length === 0: action-complete