diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp index 110bcda..e9235a7 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp @@ -5221,6 +5221,37 @@ void UHyperTwistTrainingSubsystem::RefreshRepositoryViews() RepositoryViewUserId, ResolvedReferenceUtc ); + if (!bHasActiveRunContext) + { + const bool bShouldRehydrateCompletedCoachActionPlanForCarryover = + ActiveReviewProgramSummary.bHasCarryover + && !ActiveCoachActionPlanSummary.LastCompletedPlanId.IsEmpty(); + const FString RepositoryCoachActionPlanId = + !ActiveCoachActionPlanSummary.CurrentPlanId.IsEmpty() + ? ActiveCoachActionPlanSummary.CurrentPlanId + : (bShouldRehydrateCompletedCoachActionPlanForCarryover + ? ActiveCoachActionPlanSummary.LastCompletedPlanId + : FString()); + if (!RepositoryCoachActionPlanId.IsEmpty()) + { + FHyperTwistTrainingCoachActionPlan StoredCoachActionPlan; + const bool bHasStoredCoachActionPlan = + UHyperTwistTrainingRepositoryLibrary::TryGetCoachActionPlan( + TrainingRepositoryState, + RepositoryCoachActionPlanId, + StoredCoachActionPlan + ); + ActiveCoachActionPlan = bHasStoredCoachActionPlan + && StoredCoachActionPlan.IsStructurallyValid() + && StoredCoachActionPlan.UserId == RepositoryViewUserId + ? StoredCoachActionPlan + : FHyperTwistTrainingCoachActionPlan(); + } + else + { + ActiveCoachActionPlan = FHyperTwistTrainingCoachActionPlan(); + } + } ActiveCoachActionPlanOutcomeSummary = ActiveCoachActionPlan.IsStructurallyValid() ? UHyperTwistTrainingRepositoryLibrary::DeriveCoachActionPlanOutcomeSummary( TrainingRepositoryState, diff --git a/docs/arch/HYPERTWIST_PHASE4_POST_CLEAR_ACTION_PLAN_CONTINUITY_PACKET_2026-05-06.md b/docs/arch/HYPERTWIST_PHASE4_POST_CLEAR_ACTION_PLAN_CONTINUITY_PACKET_2026-05-06.md new file mode 100644 index 0000000..bb78b76 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_POST_CLEAR_ACTION_PLAN_CONTINUITY_PACKET_2026-05-06.md @@ -0,0 +1,96 @@ +# HyperTwist Phase 4 post-clear action-plan continuity packet + +Created on `2026-05-06` + +Status: + +- first-party HyperTwist packet +- bounded Phase `4` coach-to-review validation slice + +## Purpose + +This packet restores coach action-plan continuity after `ClearActiveRun()` when review carryover is still alive in repository state. + +The open tasks are: + +- stop dropping the repository-backed coach action plan at the clear-run boundary when pending review carryover still depends on that plan's closure and outcome context +- let post-clear queue/follow-up reconstruction keep using the correct action-plan context until the review carryover is actually consumed + +It is not: + +- a new review-plan persistence packet +- a new queue-state packet +- a new dashboard-surface packet +- a broader coach-guidance redesign + +## Scope + +Bounded lane: + +- rehydrate the repository-backed coach action plan during `RefreshRepositoryViews()` when no run is active and either an open coach action plan still exists or review carryover still needs the last completed plan +- keep the coach action plan cleared when there is no active run and no remaining carryover pressure +- preserve the existing true-idle closure behavior once the review loop is genuinely exhausted + +Out of scope: + +- changing review finalization rules +- changing queue execution history retention +- rewriting coach brief derivation +- widening into broader runtime consumers + +## Why this was the right next packet + +Before this slice: + +- review carryover could survive run completion and clear-run correctly in repository-backed review state +- idle review-plan rehydration, completed-review idle closure, and dashboard idle-surface closure were already landed + +But one continuity seam still remained: + +- `ClearActiveRun()` reset `ActiveCoachActionPlan` +- `RefreshRepositoryViews()` rehydrated review plans, but it did not rehydrate the coach action plan that post-clear queue and follow-up reconstruction still depends on + +That meant: + +- review carryover could still exist underneath +- while the subsystem had already lost the action-plan context needed to rebuild the right follow-up and closure-derived guidance above that carryover + +So the next honest move was: + +- rehydrate the repository-backed coach action plan only while it is still operationally relevant +- and keep it cleared once the loop reaches true idle closure + +## What landed + +Primary code changes: + +- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp` + - `RefreshRepositoryViews()` now derives the coach action-plan summary before coach-action outcome/closure reconstruction + - when there is no active run, it rehydrates the current coach action plan if one is still open + - when there is no open coach action plan but review carryover still exists, it rehydrates the last completed coach action plan so closure-derived post-clear guidance can survive correctly + - when neither condition applies, it keeps `ActiveCoachActionPlan` cleared so final idle closure remains truthful + +## Product effect + +The post-clear carryover lane is now more coherent: + +- repository-backed review carryover no longer loses the coach action-plan context it still needs at the clear-run boundary +- post-clear follow-up and queue reconstruction can keep using the right closure/outcome context until carryover is consumed +- once carryover is gone, the system still collapses back to true idle rather than retaining stale action-plan pressure + +## Acceptance criteria + +- when a run is cleared and review carryover still exists, repository refresh rehydrates the relevant coach action plan instead of dropping it +- post-clear coach derived state can still use that action-plan context to rebuild the correct continuity lane +- when there is no remaining carryover or open coach plan, the action plan remains cleared +- full product build succeeds + +## Validation checklist + +1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor` +2. confirm `RefreshRepositoryViews()` rehydrates the current action plan when one is still open and no run is active +3. confirm it rehydrates the last completed action plan when carryover remains but no open action plan exists +4. confirm it clears `ActiveCoachActionPlan` when there is no remaining carryover and no open plan +5. confirm no broader idle-closure packet is reopened + +That is the packet.