Feature: Plan Generation Coverage Boost Scenarios that exercise previously uncovered defensive code paths in the plan_generation module (lines 90-91, 428-429, 491, 631-635). Background: Given the plan generation coverage module is imported Scenario: BoundedMemorySaver prune handles corrupt checkpoint data gracefully Given a BoundedMemorySaver with max_checkpoints set to 1 And the saver storage contains two checkpoints with corrupt data When the saver prunes the oldest checkpoint Then the prune should complete without error And the corrupt checkpoint should be removed from storage Scenario: _generate_plan falls back to None when read_text raises an exception Given a PlanGenerationGraph instance for coverage testing And a generate state with an explicit path pointing to an unreadable file When _generate_plan is called with the unreadable file state Then a change should be generated with None as original_content And the change operation should be MODIFY Scenario: _find_matching_context returns None when no context path matches Given a PlanGenerationGraph instance for coverage testing And a list of contexts with non-matching paths When _find_matching_context is called with a path that matches no context Then the matching context result should be None Scenario: _analyze_contexts falls back when agent.invoke raises an exception Given a PlanGenerationGraph instance for coverage testing And the ContextAnalysisAgent invoke method is mocked to raise an error When _analyze_contexts is called with non-empty contexts Then the result should contain the fallback summary And the result should contain an analysis error message And dependencies and relevance should be empty dicts