# 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 ```javascript 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 ```javascript 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