From f8a6a3637012b5f3ce551ae0f25d260d31b8ed8a Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Wed, 6 May 2026 17:14:47 +0200 Subject: [PATCH] Persist recognition review preference through coach queue --- .../HyperTwistTrainingCoachLibrary.cpp | 1 + .../HyperTwistTrainingRepositoryLibrary.cpp | 6 +- .../HyperTwistTrainingSubsystem.cpp | 3 +- .../HyperTwistTrainingCoachLibrary.h | 3 + .../HyperTwistTrainingTypes.h | 3 + ...ON_REVIEW_PERSISTENCE_PACKET_2026-05-06.md | 99 +++++++++++++++++++ 6 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 docs/arch/HYPERTWIST_PHASE4_QUEUE_RECOGNITION_REVIEW_PERSISTENCE_PACKET_2026-05-06.md diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp index 01a1270..a175a2e 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp @@ -3783,6 +3783,7 @@ FHyperTwistCoachSessionQueueSummary UHyperTwistTrainingCoachLibrary::DeriveCoach Entry.FocusCaseIds = Brief.FocusCaseIds; Entry.bRequiresFollowUp = bRequiresFollowUp; Entry.bRequiresArchiveRetentionTuning = bRequiresArchiveRetentionTuning; + Entry.bPreferRecognitionReplayReview = Brief.bPreferRecognitionReplayReview; const bool bNarrowedContinuationPreferred = HyperTwistTrainingCoachLibraryInternal::IsDeferredOverflowDashboardHandoffSource( CoachMemorySnapshot.PreferredCoachHandoffSourceLabel diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp index 264195a..f5b5232 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp @@ -4829,14 +4829,15 @@ namespace HyperTwistTrainingRepositoryLibraryInternal { const FString CaseFingerprint = FString::Join(Entry.FocusCaseIds, TEXT("|")); return FString::Printf( - TEXT("%s|%s|%s|%s|%d|%d|%s"), + TEXT("%s|%s|%s|%s|%d|%d|%s|%d"), *Entry.SourceLabel, *Entry.FocusDeckId, *Entry.FocusMethodSegmentId, *Entry.Headline, static_cast(Entry.SuggestedMode), static_cast(Entry.SuggestedSelectionPolicy), - *CaseFingerprint + *CaseFingerprint, + Entry.bPreferRecognitionReplayReview ? 1 : 0 ); } @@ -20676,6 +20677,7 @@ FHyperTwistTrainingCoachSessionQueueState UHyperTwistTrainingRepositoryLibrary:: QueueEntry.FocusCaseIds = SummaryEntry.FocusCaseIds; QueueEntry.bRequiresFollowUp = SummaryEntry.bRequiresFollowUp; QueueEntry.bRequiresArchiveRetentionTuning = SummaryEntry.bRequiresArchiveRetentionTuning; + QueueEntry.bPreferRecognitionReplayReview = SummaryEntry.bPreferRecognitionReplayReview; QueueEntry.bPinned = QueueEntry.bRequiresFollowUp || QueueEntry.bRequiresArchiveRetentionTuning; QueueEntry.EntryState = EHyperTwistTrainingCoachSessionQueueEntryState::Pending; QueueEntry.WorkFingerprint = diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp index 3c8f0e0..a04b442 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp @@ -1143,8 +1143,7 @@ namespace HyperTwistTrainingSubsystemInternal Brief.FocusMethodSegmentId = QueueEntry.FocusMethodSegmentId; Brief.FocusCaseIds = QueueEntry.FocusCaseIds; Brief.bNeedsCoachReview = QueueEntry.SuggestedMode == EHyperTwistTrainingDeliveryMode::CoachReviewed; - Brief.bPreferRecognitionReplayReview = - QueueEntry.SuggestedMode == EHyperTwistTrainingDeliveryMode::RecognitionAssisted; + Brief.bPreferRecognitionReplayReview = QueueEntry.bPreferRecognitionReplayReview; return Brief; } diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h index a319b40..ef22ea4 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h @@ -194,6 +194,9 @@ struct FHyperTwistCoachSessionQueueEntry UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") bool bRequiresArchiveRetentionTuning = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreferRecognitionReplayReview = false; }; USTRUCT(BlueprintType) diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h index 5914c72..45026ea 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h @@ -4248,6 +4248,9 @@ struct FHyperTwistTrainingCoachSessionQueueStateEntry UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") bool bRequiresArchiveRetentionTuning = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreferRecognitionReplayReview = false; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") bool bPinned = false; diff --git a/docs/arch/HYPERTWIST_PHASE4_QUEUE_RECOGNITION_REVIEW_PERSISTENCE_PACKET_2026-05-06.md b/docs/arch/HYPERTWIST_PHASE4_QUEUE_RECOGNITION_REVIEW_PERSISTENCE_PACKET_2026-05-06.md new file mode 100644 index 0000000..44fda9d --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE4_QUEUE_RECOGNITION_REVIEW_PERSISTENCE_PACKET_2026-05-06.md @@ -0,0 +1,99 @@ +# HyperTwist Phase 4 queue recognition review persistence packet + +Created on `2026-05-06` + +Status: + +- first-party HyperTwist packet +- bounded Phase `4` replay-to-coach and queue-to-run continuity slice + +## Purpose + +This packet closes the next continuity gap after the landed recognition review continuity slice. + +The open task is: + +- preserve recognition-review preference through coach-session queue summary/state storage and queue-backed brief reconstruction + +It is not: + +- a new recognition provider packet +- a dashboard redesign +- a replay analytics rewrite +- a broad coach-queue redesign + +## Scope + +Bounded lane: + +- add explicit recognition-review preference storage to coach-session queue entries and queue-state entries +- carry that preference from coach brief into: + - queue summary derivation + - persisted queue state + - queue entry work fingerprinting +- reconstruct queue-backed coach briefs from the explicit stored preference rather than inferring it from delivery mode alone + +Out of scope: + +- new recognition scoring rules +- changes to recognition transport or provider health +- new action-plan heuristics +- broad queue prioritization changes + +## Why this was the right next packet + +Before this slice: + +- the previous packet unified replay-derived recognition-review preference inside coach signal and coach brief derivation +- but the queue lane still collapsed that preference during persistence and restoration +- queue-backed brief reconstruction re-inferred recognition-review preference only from `RecognitionAssisted` mode + +That left one remaining continuity hole: + +- recognition-review pressure that should survive as explicit coach intent could still be lost once the brief was materialized into queue state and rebuilt for execution + +So the next honest move was: + +- make the queue lane preserve recognition-review preference as first-class state + +## What landed + +Primary code changes: + +- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h` + - added recognition-review preference to queue-summary entries +- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h` + - added recognition-review preference to queue-state entries +- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp` + - queue-summary derivation now persists recognition-review preference from the brief +- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp` + - queue-state construction now persists the flag + - queue-entry fingerprinting now includes the flag +- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp` + - queue-backed brief reconstruction now uses the stored flag directly + +## Product effect + +Recognition-review preference is now preserved across the queue lane: + +- replay-derived recognition-review pressure survives queue summary generation +- persisted queue state no longer drops that preference +- queue-backed run launch and follow-on coach consumers rebuild briefs from the explicit stored intent instead of assuming recognition preference only when mode is `RecognitionAssisted` + +## Acceptance criteria + +- queue summary entries can carry recognition-review preference explicitly +- queue state entries persist that preference explicitly +- queue entry work fingerprints change when recognition-review preference changes +- queue-backed brief reconstruction reads the stored preference directly +- full product build succeeds + +## Validation checklist + +1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor` +2. confirm queue-summary derivation persists `bPreferRecognitionReplayReview` +3. confirm queue-state build and fingerprinting preserve that field +4. confirm queue-backed brief reconstruction no longer infers recognition-review preference from delivery mode alone +5. confirm no provider/session/runtime transport packet is reopened + +That is the packet.