Retire stale queue state after run clear
This commit is contained in:
parent
c7e02fe1cd
commit
b361794457
4 changed files with 150 additions and 2 deletions
|
|
@ -21232,6 +21232,27 @@ FHyperTwistTrainingRepositoryState UHyperTwistTrainingRepositoryLibrary::UpsertC
|
|||
return UpdatedRepositoryState;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRepositoryState UHyperTwistTrainingRepositoryLibrary::RemoveCoachSessionQueueState(
|
||||
const FHyperTwistTrainingRepositoryState& RepositoryState,
|
||||
const FString& UserId,
|
||||
const FString& QueueId
|
||||
)
|
||||
{
|
||||
if (UserId.IsEmpty() || QueueId.IsEmpty())
|
||||
{
|
||||
return RepositoryState;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingRepositoryState UpdatedRepositoryState = RepositoryState;
|
||||
UpdatedRepositoryState.StoredCoachSessionQueues.RemoveAll(
|
||||
[&UserId, &QueueId](const FHyperTwistTrainingCoachSessionQueueState& Candidate)
|
||||
{
|
||||
return Candidate.UserId == UserId && Candidate.QueueId == QueueId;
|
||||
}
|
||||
);
|
||||
return UpdatedRepositoryState;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingRepositoryLibrary::DeriveCoachSessionQueueExecutionSummary(
|
||||
const FHyperTwistTrainingRepositoryState& RepositoryState,
|
||||
const FString& UserId,
|
||||
|
|
|
|||
|
|
@ -3372,7 +3372,11 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartRecommendedReview
|
|||
return FHyperTwistTrainingRunState();
|
||||
}
|
||||
|
||||
const FString UserId = ActiveRunState.Session.UserId.IsEmpty() ? TEXT("local-user") : ActiveRunState.Session.UserId;
|
||||
const FString UserId = !ActiveCoachBrief.UserId.IsEmpty()
|
||||
? ActiveCoachBrief.UserId
|
||||
: (!ActiveCoachSessionQueueState.UserId.IsEmpty()
|
||||
? ActiveCoachSessionQueueState.UserId
|
||||
: (ActiveRunState.Session.UserId.IsEmpty() ? TEXT("local-user") : ActiveRunState.Session.UserId));
|
||||
FHyperTwistTrainingRunState RunState = StartTrainingRunFromDeck(ReviewDeck, UserId, SessionId, Mode);
|
||||
if (!RunState.IsStructurallyValid())
|
||||
{
|
||||
|
|
@ -3417,7 +3421,11 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachRecommendedR
|
|||
return FHyperTwistTrainingRunState();
|
||||
}
|
||||
|
||||
const FString UserId = ActiveRunState.Session.UserId.IsEmpty() ? TEXT("local-user") : ActiveRunState.Session.UserId;
|
||||
const FString UserId = !ActiveCoachBrief.UserId.IsEmpty()
|
||||
? ActiveCoachBrief.UserId
|
||||
: (!ActiveCoachSessionQueueState.UserId.IsEmpty()
|
||||
? ActiveCoachSessionQueueState.UserId
|
||||
: (ActiveRunState.Session.UserId.IsEmpty() ? TEXT("local-user") : ActiveRunState.Session.UserId));
|
||||
const FHyperTwistTrainingCoachSessionQueueState QueueStateBeforeStart = ActiveCoachSessionQueueState;
|
||||
const HyperTwistTrainingSubsystemInternal::FResolvedCoachCaseBudget LaunchBudget =
|
||||
HyperTwistTrainingSubsystemInternal::ResolvePreferredCoachCaseBudget(
|
||||
|
|
@ -5302,6 +5310,17 @@ void UHyperTwistTrainingSubsystem::RefreshRepositoryViews()
|
|||
}
|
||||
else
|
||||
{
|
||||
const FString QueueStateUserId = !ActiveCoachSessionQueueState.UserId.IsEmpty()
|
||||
? ActiveCoachSessionQueueState.UserId
|
||||
: RepositoryViewUserId;
|
||||
if (!QueueStateUserId.IsEmpty())
|
||||
{
|
||||
TrainingRepositoryState = UHyperTwistTrainingRepositoryLibrary::RemoveCoachSessionQueueState(
|
||||
TrainingRepositoryState,
|
||||
QueueStateUserId,
|
||||
HyperTwistTrainingSubsystemInternal::ActiveCoachSessionQueueId
|
||||
);
|
||||
}
|
||||
ActiveCoachSessionQueueState = FHyperTwistTrainingCoachSessionQueueState();
|
||||
ActiveCoachScheduleHorizonSummary = FHyperTwistCoachScheduleHorizonSummary();
|
||||
ActiveCoachSchedulePolicySummary = FHyperTwistCoachSchedulePolicySummary();
|
||||
|
|
|
|||
|
|
@ -476,6 +476,13 @@ public:
|
|||
const FHyperTwistTrainingCoachSessionQueueState& QueueState
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository|Coach")
|
||||
static FHyperTwistTrainingRepositoryState RemoveCoachSessionQueueState(
|
||||
const FHyperTwistTrainingRepositoryState& RepositoryState,
|
||||
const FString& UserId,
|
||||
const FString& QueueId
|
||||
);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository|Coach")
|
||||
static FHyperTwistTrainingCoachSessionQueueExecutionSummary DeriveCoachSessionQueueExecutionSummary(
|
||||
const FHyperTwistTrainingRepositoryState& RepositoryState,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
# HyperTwist Phase 4 post-clear queue idle continuity packet
|
||||
|
||||
Created on `2026-05-06`
|
||||
|
||||
Status:
|
||||
|
||||
- first-party HyperTwist packet
|
||||
- bounded Phase `4` coach-to-review validation slice
|
||||
|
||||
## Purpose
|
||||
|
||||
This packet closes the next post-clear execution gap in the live recognition-assisted coach-to-review loop.
|
||||
|
||||
The open tasks are:
|
||||
|
||||
- keep post-clear recovered coach launches bound to the retained learner instead of silently falling back to `local-user`
|
||||
- retire the stored active queue state when carryover-backed queue work is actually exhausted, so queue-recovery bias can collapse back to a truthful idle posture
|
||||
|
||||
It is not:
|
||||
|
||||
- a new queue-priority heuristic packet
|
||||
- a broader recommendation-history redesign
|
||||
- a new dashboard layout packet
|
||||
- a recognition transport packet
|
||||
|
||||
## Scope
|
||||
|
||||
Bounded lane:
|
||||
|
||||
- fix recovered recommended/review launches so they inherit the retained coach user context
|
||||
- add repository support for removing the active coach queue state without deleting queue history
|
||||
- clear the stored active queue state when repository-derived queue summary no longer materializes any live queue work
|
||||
- keep queue history intact so execution analytics and lineage remain available
|
||||
|
||||
Out of scope:
|
||||
|
||||
- new review scoring
|
||||
- queue-history pruning
|
||||
- broad coach-memory retuning
|
||||
- structural cleanup beyond the narrow queue retirement seam
|
||||
|
||||
## Why this was the right next packet
|
||||
|
||||
Before this slice:
|
||||
|
||||
- clear-run repository-view continuity was already landed
|
||||
- post-clear coach guidance and queue state could survive the run-clear boundary
|
||||
- queue history and queue-derived recovery signals were already part of coach-memory shaping
|
||||
|
||||
But two post-clear mismatches still remained:
|
||||
|
||||
- `StartCoachRecommendedRun()` still defaulted to `local-user` whenever there was no active run, even if the recovered coach brief already carried the correct retained user
|
||||
- when queue summary no longer produced any live queue work, the subsystem cleared only the in-memory queue state; the repository still retained the last active queue state
|
||||
|
||||
That meant:
|
||||
|
||||
- recovered recommended coach runs could bind to the wrong learner after run clear
|
||||
- queue-recovery bias could stay live in repository-derived coach memory because `DeriveQueueRecoveryBiasSnapshot()` still found a stored active queue state even after the queue should have collapsed to idle
|
||||
|
||||
So the next honest move was:
|
||||
|
||||
- align recovered launch ownership with retained coach context and retire the stored active queue state once the live queue actually disappears
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.h`
|
||||
- added repository support for removing an active coach queue state by `UserId` and `QueueId`
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp`
|
||||
- implemented `RemoveCoachSessionQueueState()` without touching queue history
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp`
|
||||
- recovered recommended/review launch paths now prefer retained coach user context before falling back to `local-user`
|
||||
- repository refresh now removes the stored active queue state when no live queue summary remains materialized
|
||||
|
||||
## Product effect
|
||||
|
||||
The post-clear execution lane is now more truthful:
|
||||
|
||||
- recovered coach launches stay attached to the retained learner identity
|
||||
- once carryover-backed queue work is gone, the stored active queue state no longer keeps queue-recovery bias artificially alive
|
||||
- queue history remains available for analytics, but active queue posture can return cleanly to idle
|
||||
- dashboard and coach-memory surfaces have a cleaner path back to “no active queue work” after carryover is actually consumed
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- post-clear recovered recommended/review launches no longer fall back to `local-user` when retained coach user context exists
|
||||
- stored active queue state is removed when repository-derived queue summary no longer materializes live queue work
|
||||
- queue history is preserved while active queue state is retired
|
||||
- repository-derived queue recovery bias can collapse after true queue exhaustion
|
||||
- full product build succeeds
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor`
|
||||
2. confirm recovered recommended/review launch paths prefer retained coach user context
|
||||
3. confirm repository refresh removes the active queue state when queue summary is no longer structurally valid
|
||||
4. confirm queue history remains untouched
|
||||
5. confirm no broader queue or coach-memory redesign was reopened
|
||||
|
||||
That is the packet.
|
||||
Loading…
Add table
Reference in a new issue