Resync coach queue state after brief refinements

This commit is contained in:
axiomlogicnexus 2026-05-06 02:51:21 +02:00
parent 8c202cba97
commit 9c8c169976
2 changed files with 176 additions and 80 deletions

View file

@ -4058,7 +4058,7 @@ void UHyperTwistTrainingSubsystem::RefreshRepositoryViews()
);
ActiveCoachSignals = ActiveCoachBrief.Signals;
}
ActiveCoachFollowUpBrief = ActiveCoachActionPlanOutcomeSummary.IsStructurallyValid()
const bool bShouldDeriveCoachFollowUpBrief = ActiveCoachActionPlanOutcomeSummary.IsStructurallyValid()
&& (
ActiveCoachActionClosureSummary.bShouldSpawnFollowUp
|| (
@ -4067,20 +4067,80 @@ void UHyperTwistTrainingSubsystem::RefreshRepositoryViews()
&& !ActiveCoachActionSequenceSummary.bHasOpenPlan
&& !ActiveCoachActionClosureSummary.bNeedsEscalation
)
)
? UHyperTwistTrainingCoachLibrary::DeriveCoachFollowUpBrief(
);
const auto RebuildActiveCoachQueueDerivedState = [&]()
{
ActiveCoachFollowUpBrief = bShouldDeriveCoachFollowUpBrief
? UHyperTwistTrainingCoachLibrary::DeriveCoachFollowUpBrief(
ActiveCoachBrief,
ActiveCoachActionPlan,
ActiveCoachActionPlanOutcomeSummary
)
: FHyperTwistCoachBrief();
ActiveCoachSessionQueueSummary = UHyperTwistTrainingCoachLibrary::DeriveCoachSessionQueueSummary(
ActiveCoachBrief,
ActiveCoachActionPlan,
ActiveCoachActionPlanOutcomeSummary
)
: FHyperTwistCoachBrief();
ActiveCoachSessionQueueSummary = UHyperTwistTrainingCoachLibrary::DeriveCoachSessionQueueSummary(
ActiveCoachBrief,
ActiveCoachFollowUpBrief,
ActiveCoachMemorySnapshot,
ActiveCoachArchivePolicySummary,
ActiveReviewProgramSummary
);
ActiveCoachFollowUpBrief,
ActiveCoachMemorySnapshot,
ActiveCoachArchivePolicySummary,
ActiveReviewProgramSummary
);
if (ActiveCoachSessionQueueSummary.IsStructurallyValid())
{
FHyperTwistTrainingCoachSessionQueueState StoredQueueState;
const bool bHasStoredQueueState = UHyperTwistTrainingRepositoryLibrary::TryGetCoachSessionQueueState(
TrainingRepositoryState,
ActiveCoachSessionQueueSummary.UserId,
HyperTwistTrainingSubsystemInternal::ActiveCoachSessionQueueId,
StoredQueueState
);
ActiveCoachSessionQueueState = bHasStoredQueueState
? UHyperTwistTrainingRepositoryLibrary::ResolveCoachSessionQueueState(
StoredQueueState,
ActiveCoachSessionQueueSummary,
ActiveLearnerDeckStateSummary.ReferenceUtc
)
: UHyperTwistTrainingRepositoryLibrary::BuildCoachSessionQueueState(
ActiveCoachSessionQueueSummary,
HyperTwistTrainingSubsystemInternal::ActiveCoachSessionQueueId,
ActiveLearnerDeckStateSummary.ReferenceUtc
);
if (ActiveCoachSessionQueueState.IsStructurallyValid())
{
TrainingRepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertCoachSessionQueueState(
TrainingRepositoryState,
ActiveCoachSessionQueueState
);
}
ActiveCoachScheduleHorizonSummary = UHyperTwistTrainingCoachLibrary::DeriveCoachScheduleHorizonSummary(
ActiveCoachSessionQueueState,
ActiveCoachArchivePolicySummary,
ActiveLearnerDeckStateSummary.ReferenceUtc
);
ActiveCoachSchedulePolicySummary = UHyperTwistTrainingCoachLibrary::DeriveCoachSchedulePolicySummary(
ActiveCoachSessionQueueState,
ActiveCoachScheduleHorizonSummary,
ActiveCoachActionClosureSummary,
ActiveCoachMemorySnapshot,
ActiveCoachArchivePolicySummary,
ActiveLearnerDeckStateSummary.ReferenceUtc
);
ActiveCoachSessionQueueExecutionSummary =
UHyperTwistTrainingRepositoryLibrary::DeriveCoachSessionQueueExecutionSummary(
TrainingRepositoryState,
ActiveCoachSessionQueueState.UserId,
ActiveCoachSessionQueueState.QueueId,
ActiveLearnerDeckStateSummary.ReferenceUtc
);
}
else
{
ActiveCoachSessionQueueState = FHyperTwistTrainingCoachSessionQueueState();
ActiveCoachScheduleHorizonSummary = FHyperTwistCoachScheduleHorizonSummary();
ActiveCoachSchedulePolicySummary = FHyperTwistCoachSchedulePolicySummary();
ActiveCoachSessionQueueExecutionSummary = FHyperTwistTrainingCoachSessionQueueExecutionSummary();
}
};
RebuildActiveCoachQueueDerivedState();
const FHyperTwistCoachSignal QueueSuppressionSignal =
UHyperTwistTrainingCoachLibrary::DeriveQueueSuppressionSignal(
ActiveCoachSessionQueueSummary,
@ -4095,76 +4155,23 @@ void UHyperTwistTrainingSubsystem::RefreshRepositoryViews()
QueueSuppressionSignal
);
ActiveCoachSignals = ActiveCoachBrief.Signals;
RebuildActiveCoachQueueDerivedState();
}
if (ActiveCoachSessionQueueSummary.IsStructurallyValid())
{
FHyperTwistTrainingCoachSessionQueueState StoredQueueState;
const bool bHasStoredQueueState = UHyperTwistTrainingRepositoryLibrary::TryGetCoachSessionQueueState(
TrainingRepositoryState,
ActiveCoachSessionQueueSummary.UserId,
HyperTwistTrainingSubsystemInternal::ActiveCoachSessionQueueId,
StoredQueueState
);
ActiveCoachSessionQueueState = bHasStoredQueueState
? UHyperTwistTrainingRepositoryLibrary::ResolveCoachSessionQueueState(
StoredQueueState,
ActiveCoachSessionQueueSummary,
ActiveLearnerDeckStateSummary.ReferenceUtc
)
: UHyperTwistTrainingRepositoryLibrary::BuildCoachSessionQueueState(
ActiveCoachSessionQueueSummary,
HyperTwistTrainingSubsystemInternal::ActiveCoachSessionQueueId,
ActiveLearnerDeckStateSummary.ReferenceUtc
);
if (ActiveCoachSessionQueueState.IsStructurallyValid())
{
TrainingRepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertCoachSessionQueueState(
TrainingRepositoryState,
ActiveCoachSessionQueueState
);
}
ActiveCoachScheduleHorizonSummary = UHyperTwistTrainingCoachLibrary::DeriveCoachScheduleHorizonSummary(
ActiveCoachSessionQueueState,
ActiveCoachArchivePolicySummary,
ActiveLearnerDeckStateSummary.ReferenceUtc
);
ActiveCoachSchedulePolicySummary = UHyperTwistTrainingCoachLibrary::DeriveCoachSchedulePolicySummary(
ActiveCoachSessionQueueState,
ActiveCoachScheduleHorizonSummary,
ActiveCoachActionClosureSummary,
const FHyperTwistCoachSignal SchedulePolicyFeedbackSignal =
UHyperTwistTrainingCoachLibrary::DeriveSchedulePolicyFeedbackSignal(
ActiveCoachSchedulePolicySummary,
ActiveCoachSessionQueueExecutionSummary,
ActiveCoachMemorySnapshot,
ActiveCoachArchivePolicySummary,
ActiveLearnerDeckStateSummary.ReferenceUtc
ActiveCoachBrief
);
ActiveCoachSessionQueueExecutionSummary =
UHyperTwistTrainingRepositoryLibrary::DeriveCoachSessionQueueExecutionSummary(
TrainingRepositoryState,
ActiveCoachSessionQueueState.UserId,
ActiveCoachSessionQueueState.QueueId,
ActiveLearnerDeckStateSummary.ReferenceUtc
);
const FHyperTwistCoachSignal SchedulePolicyFeedbackSignal =
UHyperTwistTrainingCoachLibrary::DeriveSchedulePolicyFeedbackSignal(
ActiveCoachSchedulePolicySummary,
ActiveCoachSessionQueueExecutionSummary,
ActiveCoachMemorySnapshot,
ActiveCoachBrief
);
if (!SchedulePolicyFeedbackSignal.SignalId.IsEmpty())
{
ActiveCoachBrief = UHyperTwistTrainingCoachLibrary::RefineCoachBriefWithSchedulePolicyFeedbackSignal(
ActiveCoachBrief,
SchedulePolicyFeedbackSignal
);
ActiveCoachSignals = ActiveCoachBrief.Signals;
}
}
else
if (!SchedulePolicyFeedbackSignal.SignalId.IsEmpty())
{
ActiveCoachSessionQueueState = FHyperTwistTrainingCoachSessionQueueState();
ActiveCoachScheduleHorizonSummary = FHyperTwistCoachScheduleHorizonSummary();
ActiveCoachSchedulePolicySummary = FHyperTwistCoachSchedulePolicySummary();
ActiveCoachSessionQueueExecutionSummary = FHyperTwistTrainingCoachSessionQueueExecutionSummary();
ActiveCoachBrief = UHyperTwistTrainingCoachLibrary::RefineCoachBriefWithSchedulePolicyFeedbackSignal(
ActiveCoachBrief,
SchedulePolicyFeedbackSignal
);
ActiveCoachSignals = ActiveCoachBrief.Signals;
RebuildActiveCoachQueueDerivedState();
}
}

View file

@ -0,0 +1,89 @@
# HyperTwist Phase 3 coach derived-state resync packet
Created on `2026-05-06`
Status:
- first-party HyperTwist packet
- bounded coaching-stack closure slice
## Purpose
This packet defines the next logical Phase 3 closure task after the live schedule-policy feedback loop landed.
The open task is:
- keep the final active coach brief synchronized with the downstream follow-up brief, queue summary, queue state, and queue policy/execution summaries when late same-pass brief refinements fire
It is not:
- a new queue heuristic pass
- an iterative multi-pass coaching solver
- a dashboard redesign
- a donor widening task
## Scope
Bounded lane:
- same-pass resynchronization of downstream coach derived state after late brief refinements
Required result:
- `RefreshRepositoryViews()` rebuilds downstream coach queue-derived surfaces after queue-suppression and schedule-policy feedback refinements
- the final `ActiveCoachBrief`, `ActiveCoachFollowUpBrief`, `ActiveCoachSessionQueueSummary`, and `ActiveCoachSessionQueueState` all describe the same refresh-pass result
Out of scope:
- changing the scoring heuristics of the existing signals
- introducing unbounded re-derivation loops
- changing generated-mode execution behavior
- changing external plugin copies
## Current owned product truth
These pieces are already live in first-party code:
- late brief refinements for closure history, launch-budget history, queue suppression, and live schedule-policy feedback
- queue summary, queue state, queue horizon, schedule policy, and queue execution derivation
- dashboard consumers that read both coach briefs and queue-derived summaries
What was still missing:
- same-pass rebuild of downstream coach queue-derived state after late brief refinements changed the current brief
- protection against drift where the final active coach brief and the launchable follow-up/queue surfaces no longer matched each other
## Implementation target
The slice should do the following:
1. centralize same-pass rebuild of:
- `ActiveCoachFollowUpBrief`
- `ActiveCoachSessionQueueSummary`
- `ActiveCoachSessionQueueState`
- `ActiveCoachScheduleHorizonSummary`
- `ActiveCoachSchedulePolicySummary`
- `ActiveCoachSessionQueueExecutionSummary`
2. run that rebuild once after the initial coach-brief history refinements
3. run it again after queue-suppression refinement if that refinement fires
4. run it again after schedule-policy feedback refinement if that refinement fires
## Suggested file ownership
Primary edit surface:
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSubsystem.cpp`
## Acceptance criteria
- final active brief and downstream follow-up/queue surfaces are same-pass aligned
- follow-up deck, queue entry launch, and panel state now consume queue-derived state that matches the final refined brief
- full UE build still succeeds
## Validation checklist
1. build `UnrealHyperTwist.sln`
2. confirm the subsystem rebuilds queue-derived surfaces after late brief refinements
3. confirm the final refresh-pass state no longer leaves `ActiveCoachFollowUpBrief` / `ActiveCoachSessionQueueSummary` stale relative to `ActiveCoachBrief`
That is the packet.