Expose comparable peer confidence lanes
This commit is contained in:
parent
badbd4a082
commit
313aa01cec
2 changed files with 195 additions and 1 deletions
|
|
@ -121,6 +121,10 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
|
||||
);
|
||||
|
||||
FString BuildTemplateLaunchComparablePeerConfidenceLaneFragment(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
|
||||
);
|
||||
|
||||
bool HasTemplateLaunchComparablePeerEvidenceForConfidenceBonus(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats,
|
||||
int32* OutComparablePeerOutcomeRuns = nullptr,
|
||||
|
|
@ -153,7 +157,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
}
|
||||
|
||||
return FString::Printf(
|
||||
TEXT("avg recommended %d | avg focus %d | avg completed attempts %d | total success/failure/timeout/dnf %d/%d/%d/%d | avg mistakes %.2f | review-backed %d | coach-review %d | short set %d | selector split %s | tie-break support %s | peer support split %s | last launch %s | last completed %s"),
|
||||
TEXT("avg recommended %d | avg focus %d | avg completed attempts %d | total success/failure/timeout/dnf %d/%d/%d/%d | avg mistakes %.2f | review-backed %d | coach-review %d | short set %d | selector split %s | tie-break support %s | peer support split %s | comparable-peer confidence %s | last launch %s | last completed %s"),
|
||||
TemplateStats->AverageRecommendedCaseCount,
|
||||
TemplateStats->AverageFocusCaseCount,
|
||||
TemplateStats->AverageCompletedAttemptCount,
|
||||
|
|
@ -168,6 +172,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
*BuildTemplateLaunchSelectionSplitAnalyticsFragment(TemplateStats),
|
||||
*BuildTemplateLaunchAnalyticsTieBreakSupportSplitFragment(TemplateStats),
|
||||
*BuildTemplateLaunchAnalyticsTieBreakPeerDispositionSplitFragment(TemplateStats),
|
||||
*BuildTemplateLaunchComparablePeerConfidenceLaneFragment(TemplateStats),
|
||||
TemplateStats->LastLaunchAtUtc.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *TemplateStats->LastLaunchAtUtc,
|
||||
|
|
@ -536,6 +541,128 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
);
|
||||
}
|
||||
|
||||
FString BuildTemplateLaunchComparablePeerConfidenceLaneFragment(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
|
||||
)
|
||||
{
|
||||
if (TemplateStats == nullptr || !TemplateStats->IsStructurallyValid())
|
||||
{
|
||||
return TEXT("no comparable-peer confidence lane is available for this template id yet");
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats& SplitConfidenceStats =
|
||||
TemplateStats->DashboardAnalyticsTieBreakSelectorSplitConfidenceStats;
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats& PeerNoEvidenceStats =
|
||||
TemplateStats
|
||||
->DashboardAnalyticsTieBreakSelectorSplitConfidencePeerLackedComparableEvidenceStats;
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats& PeerWeakerStats =
|
||||
TemplateStats
|
||||
->DashboardAnalyticsTieBreakSelectorSplitConfidencePeerFailedWeakerSupportKindStats;
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats& PeerMarginalStats =
|
||||
TemplateStats
|
||||
->DashboardAnalyticsTieBreakSelectorSplitConfidencePeerFailedMarginalSupportKindStats;
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats& PeerClearedStats =
|
||||
TemplateStats
|
||||
->DashboardAnalyticsTieBreakSelectorSplitConfidencePeerClearedComparableGuardStats;
|
||||
if (!SplitConfidenceStats.IsStructurallyValid()
|
||||
&& !PeerNoEvidenceStats.IsStructurallyValid()
|
||||
&& !PeerWeakerStats.IsStructurallyValid()
|
||||
&& !PeerMarginalStats.IsStructurallyValid()
|
||||
&& !PeerClearedStats.IsStructurallyValid())
|
||||
{
|
||||
return TEXT("no comparable-peer confidence lane is available for this template id yet");
|
||||
}
|
||||
|
||||
auto BuildCombinedLaneSummary =
|
||||
[](
|
||||
const TCHAR* LaneLabel,
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats* FirstStats,
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats* SecondStats,
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats* ThirdStats)
|
||||
{
|
||||
int32 LaunchCount = 0;
|
||||
int32 OutcomeRunCount = 0;
|
||||
int32 TotalCompletedAttemptCount = 0;
|
||||
int32 TotalSuccessCount = 0;
|
||||
double MistakeAccumulator = 0.0;
|
||||
bool bHasAnyStats = false;
|
||||
auto AccumulateStats =
|
||||
[&](
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats* SourceStats)
|
||||
{
|
||||
if (SourceStats == nullptr || !SourceStats->IsStructurallyValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bHasAnyStats = true;
|
||||
LaunchCount += SourceStats->LaunchCount;
|
||||
OutcomeRunCount += SourceStats->GetOutcomeRunCount();
|
||||
TotalCompletedAttemptCount += SourceStats->TotalCompletedAttemptCount;
|
||||
TotalSuccessCount += SourceStats->TotalSuccessCount;
|
||||
MistakeAccumulator += static_cast<double>(
|
||||
SourceStats->AverageMistakesPerOutcomeRun)
|
||||
* static_cast<double>(SourceStats->GetOutcomeRunCount());
|
||||
};
|
||||
AccumulateStats(FirstStats);
|
||||
AccumulateStats(SecondStats);
|
||||
AccumulateStats(ThirdStats);
|
||||
|
||||
if (!bHasAnyStats)
|
||||
{
|
||||
return FString::Printf(TEXT("%s none yet"), LaneLabel);
|
||||
}
|
||||
|
||||
const float SuccessRate = TotalCompletedAttemptCount > 0
|
||||
? static_cast<float>(TotalSuccessCount)
|
||||
/ static_cast<float>(TotalCompletedAttemptCount)
|
||||
: 0.0f;
|
||||
const float AverageMistakes = OutcomeRunCount > 0
|
||||
? static_cast<float>(
|
||||
MistakeAccumulator / static_cast<double>(OutcomeRunCount))
|
||||
: 0.0f;
|
||||
return FString::Printf(
|
||||
TEXT("%s launches %d | outcomes %d | success %.2f | avg mistakes %.2f"),
|
||||
LaneLabel,
|
||||
LaunchCount,
|
||||
OutcomeRunCount,
|
||||
SuccessRate,
|
||||
AverageMistakes
|
||||
);
|
||||
};
|
||||
|
||||
int32 ComparablePeerOutcomeRuns = 0;
|
||||
int32 SplitConfidenceOutcomeRuns = 0;
|
||||
int32 PeerNoEvidenceOutcomeRuns = 0;
|
||||
float ComparablePeerOutcomeShare = 0.0f;
|
||||
const bool bGuardEarned = HasTemplateLaunchComparablePeerEvidenceForConfidenceBonus(
|
||||
TemplateStats,
|
||||
&ComparablePeerOutcomeRuns,
|
||||
&SplitConfidenceOutcomeRuns,
|
||||
&ComparablePeerOutcomeShare,
|
||||
&PeerNoEvidenceOutcomeRuns
|
||||
);
|
||||
|
||||
return FString::Printf(
|
||||
TEXT("%s | %s | guard %s comparable-peer %d/%d outcomes share %.2f | peer-no-evidence %d"),
|
||||
*BuildCombinedLaneSummary(
|
||||
TEXT("comparable-peer-backed"),
|
||||
&PeerWeakerStats,
|
||||
&PeerMarginalStats,
|
||||
&PeerClearedStats),
|
||||
*BuildCombinedLaneSummary(
|
||||
TEXT("peer-no-evidence-heavy"),
|
||||
&PeerNoEvidenceStats,
|
||||
nullptr,
|
||||
nullptr),
|
||||
bGuardEarned ? TEXT("earned") : TEXT("suppressed"),
|
||||
ComparablePeerOutcomeRuns,
|
||||
SplitConfidenceOutcomeRuns,
|
||||
ComparablePeerOutcomeShare,
|
||||
PeerNoEvidenceOutcomeRuns
|
||||
);
|
||||
}
|
||||
|
||||
FString BuildTemplateLaunchSelectionAnalyticsSupportDetailFragment(
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
# HyperTwist Phase 4 template launch comparable-peer confidence lanes packet
|
||||
|
||||
Created on `2026-05-07`
|
||||
|
||||
Status:
|
||||
|
||||
- first-party HyperTwist packet
|
||||
- bounded Phase `4` dashboard analytics visibility slice
|
||||
|
||||
## Purpose
|
||||
|
||||
This packet surfaces the comparable-peer confidence guard result directly in shared template analytics detail by collapsing selector-split-confidence history into two operator-facing lanes:
|
||||
|
||||
- `comparable-peer-backed`
|
||||
- `peer-no-evidence-heavy`
|
||||
|
||||
That makes it obvious whether confidence reinforcement is currently earned on peers with comparable support-kind evidence or suppressed because the template leans too heavily on empty peer lanes.
|
||||
|
||||
## Scope
|
||||
|
||||
Bounded lane:
|
||||
|
||||
- keep the existing raw peer support split
|
||||
- synthesize two shared analytics lanes from the repo-backed peer disposition buckets
|
||||
- append guard-earned / guard-suppressed status plus comparable-peer count/share to the shared template analytics detail
|
||||
- let preferred template launch, template launch history, and template-backed recap inherit that visibility automatically
|
||||
|
||||
Out of scope:
|
||||
|
||||
- changing selector scoring again
|
||||
- widening repository schema
|
||||
- adding a dedicated dashboard panel
|
||||
- changing persisted provenance
|
||||
|
||||
## What landed
|
||||
|
||||
Primary code changes:
|
||||
|
||||
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistCoachDashboardWidget.cpp`
|
||||
- added a shared formatter that combines peer-weaker, peer-marginal, and peer-cleared buckets into a `comparable-peer-backed` lane
|
||||
- keeps the `peer-no-evidence-heavy` lane separate from the peer-no-evidence bucket
|
||||
- reports whether the comparable-peer guard is currently earned or suppressed, along with comparable-peer outcome count/share and peer-no-evidence outcome count
|
||||
- appends that synthesized confidence-lane view to the existing shared template analytics detail
|
||||
|
||||
## Product effect
|
||||
|
||||
Operators now get a quick confidence readout anywhere shared template analytics are shown:
|
||||
|
||||
- live `[Template Launch]` detail shows whether selector-split confidence is currently earned on comparable-peer-backed history
|
||||
- template launch history shows the same lane split for the selected history row's template
|
||||
- template-backed recap shows the same lane split for the displayed run's template
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- shared template analytics detail shows `comparable-peer-backed` and `peer-no-evidence-heavy` confidence lanes
|
||||
- shared detail shows guard-earned / guard-suppressed state with comparable-peer count/share
|
||||
- live launch detail, template history, and recap all inherit the new lane split through the shared analytics fragment
|
||||
- full product build succeeds
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor`
|
||||
2. confirm shared template analytics detail includes both confidence lanes
|
||||
3. confirm shared detail shows guard-earned / guard-suppressed state with comparable-peer outcome count/share
|
||||
4. confirm preferred template launch, template history, and recap all inherit the synthesized confidence lanes
|
||||
|
||||
That is the packet.
|
||||
Loading…
Add table
Reference in a new issue