Restore carryover review queue execution continuity
This commit is contained in:
parent
a2d2f089bb
commit
63d0b37594
3 changed files with 239 additions and 3 deletions
|
|
@ -1199,6 +1199,100 @@ namespace HyperTwistTrainingSubsystemInternal
|
|||
);
|
||||
}
|
||||
|
||||
bool IsStartableCoachQueueEntryState(const EHyperTwistTrainingCoachSessionQueueEntryState EntryState)
|
||||
{
|
||||
return EntryState == EHyperTwistTrainingCoachSessionQueueEntryState::Pending
|
||||
|| EntryState == EHyperTwistTrainingCoachSessionQueueEntryState::Ready
|
||||
|| EntryState == EHyperTwistTrainingCoachSessionQueueEntryState::InProgress;
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingCoachSessionQueueStateEntry* FindCarryoverResumeQueueEntry(
|
||||
const FHyperTwistTrainingCoachSessionQueueState& QueueState,
|
||||
const FHyperTwistTrainingReviewPlanState& ReviewPlan,
|
||||
const FHyperTwistTrainingCoachActionPlan& CarryForwardActionPlan,
|
||||
const FHyperTwistTrainingDeck& ReviewDeck
|
||||
)
|
||||
{
|
||||
if (!QueueState.IsStructurallyValid())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const FString RootPlanId = !CarryForwardActionPlan.RootPlanId.IsEmpty()
|
||||
? CarryForwardActionPlan.RootPlanId
|
||||
: CarryForwardActionPlan.PlanId;
|
||||
const TArray<FString> ReviewCaseIds = ExtractCaseIdsFromDeck(ReviewDeck);
|
||||
const auto CountOverlap = [&ReviewCaseIds](const TArray<FString>& CandidateCaseIds) -> int32
|
||||
{
|
||||
int32 MatchCount = 0;
|
||||
for (const FString& ReviewCaseId : ReviewCaseIds)
|
||||
{
|
||||
if (!ReviewCaseId.IsEmpty() && CandidateCaseIds.Contains(ReviewCaseId))
|
||||
{
|
||||
MatchCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchCount;
|
||||
};
|
||||
|
||||
const FHyperTwistTrainingCoachSessionQueueStateEntry* BestEntry = nullptr;
|
||||
int32 BestScore = 0;
|
||||
for (const FHyperTwistTrainingCoachSessionQueueStateEntry& Entry : QueueState.Entries)
|
||||
{
|
||||
if (!Entry.IsStructurallyValid() || !IsStartableCoachQueueEntryState(Entry.EntryState))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int32 Score = 0;
|
||||
if (!ReviewPlan.PlanId.IsEmpty() && Entry.SourceReviewPlanId == ReviewPlan.PlanId)
|
||||
{
|
||||
Score += 500;
|
||||
}
|
||||
if (!CarryForwardActionPlan.PlanId.IsEmpty()
|
||||
&& Entry.CarryForwardPlanId == CarryForwardActionPlan.PlanId)
|
||||
{
|
||||
Score += 350;
|
||||
}
|
||||
if (!RootPlanId.IsEmpty() && Entry.RootPlanId == RootPlanId)
|
||||
{
|
||||
Score += 200;
|
||||
}
|
||||
if (!CarryForwardActionPlan.SourceSessionId.IsEmpty()
|
||||
&& Entry.SourceBriefTrainingSessionId == CarryForwardActionPlan.SourceSessionId)
|
||||
{
|
||||
Score += 125;
|
||||
}
|
||||
if (!ReviewPlan.SourceDeckId.IsEmpty() && Entry.FocusDeckId == ReviewPlan.SourceDeckId)
|
||||
{
|
||||
Score += 75;
|
||||
}
|
||||
|
||||
const int32 OverlapCount = CountOverlap(Entry.FocusCaseIds);
|
||||
if (OverlapCount > 0)
|
||||
{
|
||||
Score += OverlapCount * 20;
|
||||
if (OverlapCount == ReviewCaseIds.Num())
|
||||
{
|
||||
Score += 40;
|
||||
}
|
||||
}
|
||||
if (!QueueState.ActiveEntryId.IsEmpty() && Entry.EntryId == QueueState.ActiveEntryId)
|
||||
{
|
||||
Score += 10;
|
||||
}
|
||||
|
||||
if (Score > BestScore)
|
||||
{
|
||||
BestScore = Score;
|
||||
BestEntry = &Entry;
|
||||
}
|
||||
}
|
||||
|
||||
return BestEntry;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingDeck BuildCoachQueueDeckFromEntry(
|
||||
const FHyperTwistTrainingCoachSessionQueueStateEntry& QueueEntry,
|
||||
const FHyperTwistTrainingRunState& ActiveRunState,
|
||||
|
|
@ -4002,6 +4096,7 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartRecommendedReview
|
|||
const FHyperTwistTrainingCoachActionPlan StoredCoachActionPlan = ActiveCoachActionPlan;
|
||||
const FHyperTwistCoachBrief StoredCoachBrief = ActiveCoachBrief;
|
||||
const FHyperTwistCoachBrief StoredCoachFollowUpBrief = ActiveCoachFollowUpBrief;
|
||||
const FHyperTwistTrainingCoachSessionQueueState StoredCoachQueueState = ActiveCoachSessionQueueState;
|
||||
const FHyperTwistTrainingDeck ReviewDeck = BuildActiveReviewDeck(MaxCases);
|
||||
if (!ReviewDeck.IsStructurallyValid())
|
||||
{
|
||||
|
|
@ -4063,6 +4158,45 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartRecommendedReview
|
|||
);
|
||||
}
|
||||
}
|
||||
if (StoredCoachQueueState.IsStructurallyValid())
|
||||
{
|
||||
FHyperTwistTrainingCoachSessionQueueState RepositoryQueueState;
|
||||
const bool bHasRepositoryQueueState =
|
||||
UHyperTwistTrainingRepositoryLibrary::TryGetCoachSessionQueueState(
|
||||
TrainingRepositoryState,
|
||||
StoredCoachQueueState.UserId,
|
||||
StoredCoachQueueState.QueueId,
|
||||
RepositoryQueueState
|
||||
);
|
||||
if (bHasRepositoryQueueState)
|
||||
{
|
||||
const FHyperTwistTrainingCoachSessionQueueStateEntry* ResumeQueueEntry =
|
||||
HyperTwistTrainingSubsystemInternal::FindCarryoverResumeQueueEntry(
|
||||
RepositoryQueueState,
|
||||
StoredReviewPlan,
|
||||
StoredCoachActionPlan,
|
||||
ReviewDeck
|
||||
);
|
||||
if (ResumeQueueEntry != nullptr)
|
||||
{
|
||||
const FHyperTwistTrainingCoachSessionQueueState UpdatedQueueState =
|
||||
UHyperTwistTrainingRepositoryLibrary::StartCoachSessionQueueEntryById(
|
||||
RepositoryQueueState,
|
||||
ResumeQueueEntry->EntryId,
|
||||
RunState.Session.TrainingSessionId,
|
||||
RunState.Session.StartedAtUtc
|
||||
);
|
||||
if (UpdatedQueueState.IsStructurallyValid())
|
||||
{
|
||||
TrainingRepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertCoachSessionQueueState(
|
||||
TrainingRepositoryState,
|
||||
UpdatedQueueState
|
||||
);
|
||||
ActiveCoachSessionQueueState = UpdatedQueueState;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RefreshRepositoryViews();
|
||||
return RunState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,9 +66,9 @@ Current correction call from the source-exposed audit and current execution refr
|
|||
- retained benchmark-oracle and mirror-intake reservations
|
||||
- current code reality in which training/coaching/catalog integration is materially ahead of recognition and hypercube runtime implementation
|
||||
- the imported generated-mode gap is closed; request/config/selection plumbing and the bounded clean-room executor are already landed in first-party code
|
||||
- the latest landed bounded `Phase 4` packet closes the carryover-review action-plan resumption gap inside the already-live recognition-assisted coach-to-review continuity lane
|
||||
- resumed idle carryover review launches now rebuild and activate a fresh coach action plan tied to the resumed session instead of dropping the carried-forward closure lineage at relaunch
|
||||
- the current next bounded packet is to continue the same recognition-assisted coach-to-review closure validation pass from resumed carryover completion through final carryover consumption, review-program exhaustion, and truthful idle dashboard closure, landing only the next continuity fix that validation exposes
|
||||
- the latest landed bounded `Phase 4` packet closes the carryover-review queue execution gap inside the already-live recognition-assisted coach-to-review continuity lane
|
||||
- resumed idle carryover review launches now bind back onto any matching live queue entry so completion can close the same queue lineage that the resumed session actually consumed
|
||||
- the current next bounded packet is to continue the same recognition-assisted coach-to-review closure validation pass from queue-backed resumed carryover completion through final carryover consumption, review-program exhaustion, and truthful idle dashboard closure, landing only the next continuity fix that validation exposes
|
||||
- the current execution-discipline rule that broad refactor / monolith-splitting work should not interrupt the active bounded roadmap packet unless structure is actually blocking it
|
||||
|
||||
## Current execution-reality references
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
# HyperTwist Phase 4 carryover review queue execution continuity packet
|
||||
|
||||
Created on `2026-05-07`
|
||||
|
||||
Status:
|
||||
|
||||
- first-party HyperTwist packet
|
||||
- bounded Phase `4` coach-to-review validation slice
|
||||
|
||||
## Purpose
|
||||
|
||||
This packet preserves queue execution lineage when an idle carryover review plan resumes after `ClearActiveRun()`.
|
||||
|
||||
The open tasks are:
|
||||
|
||||
- stop relaunching a stored carryover review plan without advancing any matching live coach queue entry in repository state
|
||||
- let resumed carryover review completion close the same queue lineage it actually consumed so queue execution history, schedule feedback, and final idle collapse stay truthful
|
||||
|
||||
It is not:
|
||||
|
||||
- a new review-plan persistence packet
|
||||
- a new action-plan packet
|
||||
- a broader queue-priority redesign
|
||||
- a dashboard layout rewrite
|
||||
|
||||
## Scope
|
||||
|
||||
Bounded lane:
|
||||
|
||||
- inspect the stored live coach queue state before idle carryover review relaunch
|
||||
- resolve the best matching queue entry from review-plan lineage, carry-forward action-plan lineage, and relaunched review cases
|
||||
- mark that queue entry started against the resumed review session before the final repository refresh
|
||||
- leave queue state untouched when no matching live repository queue entry exists
|
||||
|
||||
Out of scope:
|
||||
|
||||
- changing how review plans are scored or finalized
|
||||
- changing queue ordering heuristics
|
||||
- rewriting coach follow-up derivation
|
||||
- widening into unrelated analytics or template-selection work
|
||||
|
||||
## Why this was the right next packet
|
||||
|
||||
Before this slice:
|
||||
|
||||
- idle carryover review resumption was already landed
|
||||
- resumed carryover review launches already rebuilt a fresh active coach action plan tied to the resumed session
|
||||
|
||||
But one continuity seam still remained:
|
||||
|
||||
- the resumed carryover review launch could restore review-plan lineage and action-plan lineage
|
||||
- while any matching live coach queue entry still remained unstarted in repository state
|
||||
|
||||
That meant:
|
||||
|
||||
- the resumed session could consume carryover review work correctly
|
||||
- while queue execution history and queue-derived closure feedback still had no truthful started session to close against that relaunched work
|
||||
|
||||
So the next honest move was:
|
||||
|
||||
- keep the resumed review relaunch logic
|
||||
- and bind it back onto the matching live queue entry when that queue lineage actually exists
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp`
|
||||
- added `FindCarryoverResumeQueueEntry(...)` to match a live queue entry from stored review-plan id, carry-forward/root plan lineage, and relaunched review cases
|
||||
- idle `StartRecommendedReviewRun()` now snapshots the pre-relaunch queue state
|
||||
- after relaunch, it resolves the current repository queue state, marks the matched entry started with the resumed session id via `StartCoachSessionQueueEntryById(...)`, upserts it, and then refreshes repository views
|
||||
|
||||
## Product effect
|
||||
|
||||
The resumed carryover closure lane is now more truthful:
|
||||
|
||||
- queue-backed carryover review relaunches no longer bypass queue execution lineage
|
||||
- resumed carryover review completion can now finalize the same queue entry by session id instead of leaving queue execution history blind to the relaunch
|
||||
- queue-derived schedule and closure feedback have a cleaner path back to true idle once the final carryover slice is actually consumed
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- when a stored idle carryover review plan relaunches and a matching live queue entry exists, that queue entry is marked started against the resumed session
|
||||
- when no matching live queue entry exists, the relaunch leaves queue state untouched
|
||||
- the resumed queue entry remains repository-backed so completion can finalize it by session id
|
||||
- full product build succeeds
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor`
|
||||
2. confirm idle `StartRecommendedReviewRun()` snapshots the pre-relaunch queue state
|
||||
3. confirm a matching live repository queue entry is resolved from review-plan / carry-forward lineage before queue mutation
|
||||
4. confirm resumed carryover relaunch marks that queue entry started with the resumed session id
|
||||
5. confirm no broader queue-priority or dashboard redesign was reopened
|
||||
|
||||
## Validation result
|
||||
|
||||
- full `Development Editor|Win64` build succeeded on `2026-05-07`
|
||||
|
||||
## Next bounded follow-on slice
|
||||
|
||||
- continue the same recognition-assisted coach-to-review closure validation pass from queue-backed resumed carryover completion through final carryover consumption, review-program exhaustion, and truthful idle dashboard closure, and land only the next continuity fix that validation exposes
|
||||
Loading…
Add table
Reference in a new issue