## ADDED Requirements ### Requirement: Synthesized completed plan when all sets are pinned When `openSetIds.length === 0` (every elective set has a pinned course), `useAppState` SHALL emit a single-element `topPlans` array containing a synthesized `PlanOutcome` rather than clearing the slice. The synthesized plan's fields SHALL be: - `courseAssignments`: the `pinnedAssignments` map (setId → courseId for every elective set) - `achievedSpecs`: `optimizationResult.achieved` (the optimizer's output for the same selection) - `priorityScore`: `makePriorityScorer(state.ranking)(achievedSpecs)` The other state slices (`treeResults`, `topPlansPartial`, `searchProgress`, `treeLoading`) SHALL remain in their cleared/null state for this branch — no decision-tree search runs when there are no open sets. #### Scenario: Top Plans state populates after every set is pinned - **WHEN** the user pins a course in the final remaining open set - **THEN** `topPlans` SHALL contain exactly one element whose `courseAssignments` matches the user's pinned selection - **AND** that element's `achievedSpecs` SHALL equal `optimizationResult.achieved` #### Scenario: Search progress remains null when selection is complete - **WHEN** every elective set is pinned - **THEN** `searchProgress` SHALL be `null` and `treeLoading` SHALL be `false` #### Scenario: Unpinning resumes normal search - **WHEN** the user unpins one course after the synthesized state was emitted - **THEN** the search effect SHALL run normally (cache filter, partial worker spawn) and `topPlans` SHALL reflect the cached subset and any streamed improvements