Preserve queue backed coach brief continuity
This commit is contained in:
parent
4c789b2b72
commit
b08442c335
6 changed files with 285 additions and 14 deletions
|
|
@ -3773,16 +3773,29 @@ FHyperTwistCoachSessionQueueSummary UHyperTwistTrainingCoachLibrary::DeriveCoach
|
|||
FHyperTwistCoachSessionQueueEntry Entry;
|
||||
Entry.EntryId = EntryId;
|
||||
Entry.SourceLabel = SourceLabel;
|
||||
Entry.SourceBriefTrainingSessionId = Brief.TrainingSessionId;
|
||||
Entry.SourceReviewPlanId = Brief.SourceReviewPlanId;
|
||||
Entry.CarryForwardPlanId = Brief.CarryForwardPlanId;
|
||||
Entry.RootPlanId = Brief.RootPlanId;
|
||||
Entry.FollowUpDepth = FMath::Max(0, Brief.FollowUpDepth);
|
||||
Entry.Priority = Brief.Priority;
|
||||
Entry.PriorityScore = Brief.PriorityScore;
|
||||
Entry.FocusLane = Brief.FocusLane;
|
||||
Entry.Headline = Brief.Headline;
|
||||
Entry.PrimaryActionLabel = Brief.PrimaryActionLabel;
|
||||
Entry.SuggestedMode = Brief.SuggestedMode;
|
||||
Entry.SuggestedSelectionPolicy = Brief.SuggestedSelectionPolicy;
|
||||
Entry.FocusDeckId = Brief.FocusDeckId;
|
||||
Entry.FocusMethodSegmentId = Brief.FocusMethodSegmentId;
|
||||
Entry.FocusCaseIds = Brief.FocusCaseIds;
|
||||
Entry.DeferredLaunchCaseCount = FMath::Max(0, Brief.DeferredLaunchCaseCount);
|
||||
Entry.bNeedsDeferredLaunchRecovery = Brief.bNeedsDeferredLaunchRecovery;
|
||||
Entry.bHasTightenedLaunchOverflow = Brief.bHasTightenedLaunchOverflow;
|
||||
Entry.bRequiresFollowUp = bRequiresFollowUp;
|
||||
Entry.bRequiresArchiveRetentionTuning = bRequiresArchiveRetentionTuning;
|
||||
Entry.bNeedsCoachReview = Brief.bNeedsCoachReview;
|
||||
Entry.bNeedsCadenceRecovery = Brief.bNeedsCadenceRecovery;
|
||||
Entry.bNeedsVarietyRotation = Brief.bNeedsVarietyRotation;
|
||||
Entry.bPreferRecognitionReplayReview = Brief.bPreferRecognitionReplayReview;
|
||||
const bool bNarrowedContinuationPreferred =
|
||||
HyperTwistTrainingCoachLibraryInternal::IsDeferredOverflowDashboardHandoffSource(
|
||||
|
|
|
|||
|
|
@ -4828,17 +4828,32 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
|
|||
)
|
||||
{
|
||||
const FString CaseFingerprint = FString::Join(Entry.FocusCaseIds, TEXT("|"));
|
||||
return FString::Printf(
|
||||
TEXT("%s|%s|%s|%s|%d|%d|%s|%d"),
|
||||
*Entry.SourceLabel,
|
||||
*Entry.FocusDeckId,
|
||||
*Entry.FocusMethodSegmentId,
|
||||
*Entry.Headline,
|
||||
static_cast<int32>(Entry.SuggestedMode),
|
||||
static_cast<int32>(Entry.SuggestedSelectionPolicy),
|
||||
*CaseFingerprint,
|
||||
Entry.bPreferRecognitionReplayReview ? 1 : 0
|
||||
);
|
||||
TArray<FString> FingerprintParts;
|
||||
FingerprintParts.Reserve(22);
|
||||
FingerprintParts.Add(Entry.SourceLabel);
|
||||
FingerprintParts.Add(Entry.SourceBriefTrainingSessionId);
|
||||
FingerprintParts.Add(Entry.SourceReviewPlanId);
|
||||
FingerprintParts.Add(Entry.CarryForwardPlanId);
|
||||
FingerprintParts.Add(Entry.RootPlanId);
|
||||
FingerprintParts.Add(FString::FromInt(Entry.FollowUpDepth));
|
||||
FingerprintParts.Add(Entry.FocusLaneLabel);
|
||||
FingerprintParts.Add(Entry.Headline);
|
||||
FingerprintParts.Add(Entry.PrimaryActionLabel);
|
||||
FingerprintParts.Add(Entry.FocusDeckId);
|
||||
FingerprintParts.Add(Entry.FocusMethodSegmentId);
|
||||
FingerprintParts.Add(FString::FromInt(static_cast<int32>(Entry.SuggestedMode)));
|
||||
FingerprintParts.Add(FString::FromInt(static_cast<int32>(Entry.SuggestedSelectionPolicy)));
|
||||
FingerprintParts.Add(CaseFingerprint);
|
||||
FingerprintParts.Add(FString::FromInt(Entry.DeferredLaunchCaseCount));
|
||||
FingerprintParts.Add(Entry.bNeedsDeferredLaunchRecovery ? TEXT("1") : TEXT("0"));
|
||||
FingerprintParts.Add(Entry.bHasTightenedLaunchOverflow ? TEXT("1") : TEXT("0"));
|
||||
FingerprintParts.Add(Entry.bRequiresFollowUp ? TEXT("1") : TEXT("0"));
|
||||
FingerprintParts.Add(Entry.bRequiresArchiveRetentionTuning ? TEXT("1") : TEXT("0"));
|
||||
FingerprintParts.Add(Entry.bNeedsCoachReview ? TEXT("1") : TEXT("0"));
|
||||
FingerprintParts.Add(Entry.bNeedsCadenceRecovery ? TEXT("1") : TEXT("0"));
|
||||
FingerprintParts.Add(Entry.bNeedsVarietyRotation ? TEXT("1") : TEXT("0"));
|
||||
FingerprintParts.Add(Entry.bPreferRecognitionReplayReview ? TEXT("1") : TEXT("0"));
|
||||
return FString::Join(FingerprintParts, TEXT("|"));
|
||||
}
|
||||
|
||||
FHyperTwistTrainingCoachSessionQueueState NormalizeCoachSessionQueueState(
|
||||
|
|
@ -4864,6 +4879,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
|
|||
{
|
||||
FHyperTwistTrainingCoachSessionQueueStateEntry NormalizedEntry = Entry;
|
||||
NormalizedEntry.FocusCaseIds = DeduplicateCaseIds(Entry.FocusCaseIds);
|
||||
NormalizedEntry.FollowUpDepth = FMath::Max(0, NormalizedEntry.FollowUpDepth);
|
||||
NormalizedEntry.DeferredLaunchCaseCount = FMath::Max(0, NormalizedEntry.DeferredLaunchCaseCount);
|
||||
if (NormalizedEntry.WorkFingerprint.IsEmpty())
|
||||
{
|
||||
NormalizedEntry.WorkFingerprint = MakeCoachSessionQueueEntryFingerprint(NormalizedEntry);
|
||||
|
|
@ -20664,19 +20681,34 @@ FHyperTwistTrainingCoachSessionQueueState UHyperTwistTrainingRepositoryLibrary::
|
|||
FHyperTwistTrainingCoachSessionQueueStateEntry QueueEntry;
|
||||
QueueEntry.EntryId = SummaryEntry.EntryId;
|
||||
QueueEntry.SourceLabel = SummaryEntry.SourceLabel;
|
||||
QueueEntry.SourceBriefTrainingSessionId = SummaryEntry.SourceBriefTrainingSessionId;
|
||||
QueueEntry.SourceReviewPlanId = SummaryEntry.SourceReviewPlanId;
|
||||
QueueEntry.CarryForwardPlanId = SummaryEntry.CarryForwardPlanId;
|
||||
QueueEntry.RootPlanId = SummaryEntry.RootPlanId;
|
||||
QueueEntry.FollowUpDepth = FMath::Max(0, SummaryEntry.FollowUpDepth);
|
||||
QueueEntry.SlotIndex = SummaryEntry.SlotIndex;
|
||||
QueueEntry.PriorityLabel = StaticEnum<EHyperTwistCoachPriority>()->GetNameStringByValue(
|
||||
static_cast<int64>(SummaryEntry.Priority)
|
||||
);
|
||||
QueueEntry.PriorityScore = SummaryEntry.PriorityScore;
|
||||
QueueEntry.FocusLaneLabel = StaticEnum<EHyperTwistCoachFocusLane>()->GetNameStringByValue(
|
||||
static_cast<int64>(SummaryEntry.FocusLane)
|
||||
);
|
||||
QueueEntry.Headline = SummaryEntry.Headline;
|
||||
QueueEntry.PrimaryActionLabel = SummaryEntry.PrimaryActionLabel;
|
||||
QueueEntry.SuggestedMode = SummaryEntry.SuggestedMode;
|
||||
QueueEntry.SuggestedSelectionPolicy = SummaryEntry.SuggestedSelectionPolicy;
|
||||
QueueEntry.FocusDeckId = SummaryEntry.FocusDeckId;
|
||||
QueueEntry.FocusMethodSegmentId = SummaryEntry.FocusMethodSegmentId;
|
||||
QueueEntry.FocusCaseIds = SummaryEntry.FocusCaseIds;
|
||||
QueueEntry.DeferredLaunchCaseCount = FMath::Max(0, SummaryEntry.DeferredLaunchCaseCount);
|
||||
QueueEntry.bNeedsDeferredLaunchRecovery = SummaryEntry.bNeedsDeferredLaunchRecovery;
|
||||
QueueEntry.bHasTightenedLaunchOverflow = SummaryEntry.bHasTightenedLaunchOverflow;
|
||||
QueueEntry.bRequiresFollowUp = SummaryEntry.bRequiresFollowUp;
|
||||
QueueEntry.bRequiresArchiveRetentionTuning = SummaryEntry.bRequiresArchiveRetentionTuning;
|
||||
QueueEntry.bNeedsCoachReview = SummaryEntry.bNeedsCoachReview;
|
||||
QueueEntry.bNeedsCadenceRecovery = SummaryEntry.bNeedsCadenceRecovery;
|
||||
QueueEntry.bNeedsVarietyRotation = SummaryEntry.bNeedsVarietyRotation;
|
||||
QueueEntry.bPreferRecognitionReplayReview = SummaryEntry.bPreferRecognitionReplayReview;
|
||||
QueueEntry.bPinned = QueueEntry.bRequiresFollowUp || QueueEntry.bRequiresArchiveRetentionTuning;
|
||||
QueueEntry.EntryState = EHyperTwistTrainingCoachSessionQueueEntryState::Pending;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,25 @@ namespace HyperTwistTrainingSubsystemInternal
|
|||
return TEXT("Unknown");
|
||||
}
|
||||
|
||||
template <typename TEnum>
|
||||
TEnum EnumValueFromName(const FString& Value, const TEnum Fallback)
|
||||
{
|
||||
if (Value.IsEmpty())
|
||||
{
|
||||
return Fallback;
|
||||
}
|
||||
if (const UEnum* Enum = StaticEnum<TEnum>())
|
||||
{
|
||||
const int64 RawValue = Enum->GetValueByNameString(Value);
|
||||
if (RawValue != INDEX_NONE)
|
||||
{
|
||||
return static_cast<TEnum>(RawValue);
|
||||
}
|
||||
}
|
||||
|
||||
return Fallback;
|
||||
}
|
||||
|
||||
bool ShouldPreferRecognitionReplayReviewForActiveRun(
|
||||
const FHyperTwistTrainingRunState& RunState,
|
||||
const FHyperTwistTrainingCoachActionPlan& ActionPlan
|
||||
|
|
@ -1188,19 +1207,36 @@ namespace HyperTwistTrainingSubsystemInternal
|
|||
FHyperTwistCoachBrief Brief;
|
||||
Brief.UserId = QueueState.UserId;
|
||||
Brief.ReferenceUtc = ReferenceUtc;
|
||||
Brief.TrainingSessionId = QueueEntry.SourceBriefTrainingSessionId;
|
||||
Brief.SourceReviewPlanId = QueueEntry.SourceReviewPlanId;
|
||||
Brief.CarryForwardPlanId = QueueEntry.CarryForwardPlanId;
|
||||
Brief.RootPlanId = !QueueEntry.RootPlanId.IsEmpty()
|
||||
? QueueEntry.RootPlanId
|
||||
: QueueEntry.CarryForwardPlanId;
|
||||
Brief.FollowUpDepth = FMath::Max(0, QueueEntry.FollowUpDepth);
|
||||
Brief.PriorityScore = QueueEntry.PriorityScore;
|
||||
Brief.Priority = CoachPriorityFromScore(QueueEntry.PriorityScore);
|
||||
Brief.FocusLane = QueueEntry.SourceLabel == TEXT("archive-policy")
|
||||
? EHyperTwistCoachFocusLane::Stability
|
||||
: EHyperTwistCoachFocusLane::ReviewBacklog;
|
||||
: EnumValueFromName(
|
||||
QueueEntry.FocusLaneLabel,
|
||||
EHyperTwistCoachFocusLane::ReviewBacklog
|
||||
);
|
||||
Brief.Headline = QueueEntry.Headline;
|
||||
Brief.PrimaryActionLabel = ResolveQueueActionLabel(QueueEntry.SourceLabel);
|
||||
Brief.PrimaryActionLabel = !QueueEntry.PrimaryActionLabel.IsEmpty()
|
||||
? QueueEntry.PrimaryActionLabel
|
||||
: ResolveQueueActionLabel(QueueEntry.SourceLabel);
|
||||
Brief.SuggestedMode = QueueEntry.SuggestedMode;
|
||||
Brief.SuggestedSelectionPolicy = QueueEntry.SuggestedSelectionPolicy;
|
||||
Brief.FocusDeckId = QueueEntry.FocusDeckId;
|
||||
Brief.FocusMethodSegmentId = QueueEntry.FocusMethodSegmentId;
|
||||
Brief.FocusCaseIds = QueueEntry.FocusCaseIds;
|
||||
Brief.bNeedsCoachReview = QueueEntry.SuggestedMode == EHyperTwistTrainingDeliveryMode::CoachReviewed;
|
||||
Brief.DeferredLaunchCaseCount = FMath::Max(0, QueueEntry.DeferredLaunchCaseCount);
|
||||
Brief.bNeedsDeferredLaunchRecovery = QueueEntry.bNeedsDeferredLaunchRecovery;
|
||||
Brief.bHasTightenedLaunchOverflow = QueueEntry.bHasTightenedLaunchOverflow;
|
||||
Brief.bNeedsCoachReview = QueueEntry.bNeedsCoachReview;
|
||||
Brief.bNeedsCadenceRecovery = QueueEntry.bNeedsCadenceRecovery;
|
||||
Brief.bNeedsVarietyRotation = QueueEntry.bNeedsVarietyRotation;
|
||||
Brief.bPreferRecognitionReplayReview = QueueEntry.bPreferRecognitionReplayReview;
|
||||
return Brief;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,6 +162,21 @@ struct FHyperTwistCoachSessionQueueEntry
|
|||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SourceBriefTrainingSessionId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SourceReviewPlanId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString CarryForwardPlanId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString RootPlanId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FollowUpDepth = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SlotIndex = 0;
|
||||
|
||||
|
|
@ -171,9 +186,15 @@ struct FHyperTwistCoachSessionQueueEntry
|
|||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
float PriorityScore = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistCoachFocusLane FocusLane = EHyperTwistCoachFocusLane::ReviewBacklog;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PrimaryActionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingDeliveryMode SuggestedMode = EHyperTwistTrainingDeliveryMode::Timer;
|
||||
|
||||
|
|
@ -189,12 +210,30 @@ struct FHyperTwistCoachSessionQueueEntry
|
|||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
TArray<FString> FocusCaseIds;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 DeferredLaunchCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNeedsDeferredLaunchRecovery = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasTightenedLaunchOverflow = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bRequiresFollowUp = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bRequiresArchiveRetentionTuning = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNeedsCoachReview = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNeedsCadenceRecovery = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNeedsVarietyRotation = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bPreferRecognitionReplayReview = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4190,9 +4190,24 @@ struct FHyperTwistTrainingCoachSessionQueueStateEntry
|
|||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SourceTrainingSessionId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SourceBriefTrainingSessionId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString SourceReviewPlanId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString CarryForwardPlanId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString RootPlanId;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString StartActionSourceLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 FollowUpDepth = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 SlotIndex = 0;
|
||||
|
||||
|
|
@ -4206,9 +4221,15 @@ struct FHyperTwistTrainingCoachSessionQueueStateEntry
|
|||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
float PriorityScore = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString FocusLaneLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString Headline;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString PrimaryActionLabel;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingDeliveryMode SuggestedMode = EHyperTwistTrainingDeliveryMode::Timer;
|
||||
|
||||
|
|
@ -4224,6 +4245,15 @@ struct FHyperTwistTrainingCoachSessionQueueStateEntry
|
|||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
TArray<FString> FocusCaseIds;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 DeferredLaunchCaseCount = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNeedsDeferredLaunchRecovery = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bHasTightenedLaunchOverflow = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FString ScheduledAtUtc;
|
||||
|
||||
|
|
@ -4251,6 +4281,15 @@ struct FHyperTwistTrainingCoachSessionQueueStateEntry
|
|||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bRequiresArchiveRetentionTuning = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNeedsCoachReview = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNeedsCadenceRecovery = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bNeedsVarietyRotation = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
bool bPreferRecognitionReplayReview = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
# HyperTwist Phase 4 queue brief 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 end-to-end continuity gap in the live recognition-assisted coach-to-review loop.
|
||||
|
||||
The open task is:
|
||||
|
||||
- preserve full queue-backed coach-brief semantics when coach guidance is materialized into queue entries and later reconstructed back into action-plan starts
|
||||
|
||||
It is not:
|
||||
|
||||
- a new recognition transport packet
|
||||
- a new review-policy heuristic packet
|
||||
- a new dashboard packet
|
||||
- a broad queue-system rewrite
|
||||
|
||||
## Scope
|
||||
|
||||
Bounded lane:
|
||||
|
||||
- persist the coach-brief fields that materially shape downstream coach action plans through queue summary and queue state
|
||||
- reconstruct queue-backed coach briefs from those persisted fields instead of inferring them from delivery mode or source label alone
|
||||
- keep queue fingerprints aligned with the widened preserved semantics so queue-state continuity remains honest
|
||||
|
||||
Specifically preserved through the queue lane:
|
||||
|
||||
- source brief training session id
|
||||
- source review-plan id
|
||||
- carry-forward/root plan lineage and follow-up depth
|
||||
- focus lane and primary action label
|
||||
- deferred-launch recovery state
|
||||
- coach-review, cadence-recovery, and variety-rotation flags
|
||||
- recognition-review preference
|
||||
|
||||
Out of scope:
|
||||
|
||||
- new queue prioritization rules
|
||||
- new coach-signal derivation
|
||||
- new replay scoring
|
||||
- new UI layout work
|
||||
|
||||
## Why this was the right next packet
|
||||
|
||||
Before this slice:
|
||||
|
||||
- recognition replay pressure already flowed into coach guidance
|
||||
- queue entries already preserved recognition-review preference explicitly
|
||||
- review-policy continuity and review-policy inspection were already landed
|
||||
- recognition-biased repeat pressure already escalated correctly into coach intervention
|
||||
|
||||
But the queue reconstruction lane still dropped critical coach-brief semantics:
|
||||
|
||||
- coach-review intent could collapse to `false` unless suggested mode was explicit `CoachReviewed`
|
||||
- queued follow-up entries lost carry-forward lineage
|
||||
- queue-started action plans could lose source review-plan linkage, focus lane, primary action label, and cadence/variety/deferred-launch state
|
||||
|
||||
That meant the broad Phase `4` validation lane was still not end-to-end coherent once guidance crossed the queue materialization boundary.
|
||||
|
||||
So the next honest move was:
|
||||
|
||||
- preserve queue-backed coach brief continuity directly rather than layering more downstream fixes on top of lossy queue reconstruction
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h`
|
||||
- widened queue-summary entry structure to carry the coach-brief state needed for downstream continuity
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h`
|
||||
- widened queue-state entry structure to persist the same continuity fields through repository state
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp`
|
||||
- queue summary creation now copies the relevant coach-brief semantics into queue entries
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp`
|
||||
- queue-state construction now preserves those fields and queue fingerprints now include them
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp`
|
||||
- queue-backed brief reconstruction now restores coach-review intent, review-plan linkage, follow-up lineage, focus lane, action label, deferred-launch state, cadence/variety flags, and recognition-review preference from queue state
|
||||
|
||||
## Product effect
|
||||
|
||||
Queue-backed coach execution is now materially more coherent:
|
||||
|
||||
- recognition-assisted queue entries no longer lose coach-review intent just because they run in `RecognitionAssisted` mode
|
||||
- queued follow-up guidance now preserves carry-forward/root-plan lineage into action-plan starts
|
||||
- queue-started action plans now retain the same focus lane and primary action label that shaped the original brief
|
||||
- deferred-launch, cadence, and variety state now survive the queue materialization boundary instead of resetting during reconstruction
|
||||
- dashboard queue-preview and action-plan inspection now stay closer to the original coach guidance because they read the reconstructed brief path
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- queue-backed brief reconstruction no longer infers coach-review intent from delivery mode alone
|
||||
- queue entries preserve follow-up lineage and review-plan linkage needed by downstream action-plan creation
|
||||
- queue-started action plans retain primary action label, focus lane, deferred-launch state, cadence/variety flags, and recognition-review preference
|
||||
- queue fingerprinting reflects the widened preserved semantics
|
||||
- full product build succeeds
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor`
|
||||
2. confirm queue summary entries preserve the coach-brief fields that materially affect action-plan creation
|
||||
3. confirm queue-state construction and fingerprinting preserve those widened semantics
|
||||
4. confirm queue-backed brief reconstruction restores coach-review intent, follow-up lineage, and review-plan linkage without reopening a broader packet
|
||||
5. confirm dashboard/preview surfaces continue reading the reconstructed queue-backed brief path without compile or runtime-surface regressions
|
||||
|
||||
That is the packet.
|
||||
Loading…
Add table
Reference in a new issue