Persist template-signal support-bias snapshot
This commit is contained in:
parent
78d5057205
commit
a46404dda6
3 changed files with 166 additions and 8 deletions
|
|
@ -138,6 +138,11 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
|
||||
);
|
||||
|
||||
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot
|
||||
BuildTemplateLaunchTemplateSignalSupportBiasSnapshot(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
|
||||
);
|
||||
|
||||
FString BuildTemplateLaunchComparablePeerConfidenceAuditClause(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats,
|
||||
const TCHAR* SubjectLabel
|
||||
|
|
@ -156,6 +161,10 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
|
||||
);
|
||||
|
||||
FString BuildTemplateLaunchSelectionTemplateSignalSupportBiasDetailFragment(
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
|
||||
);
|
||||
|
||||
bool HasTemplateLaunchComparablePeerEvidenceForConfidenceBonus(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats,
|
||||
int32* OutComparablePeerOutcomeRuns = nullptr,
|
||||
|
|
@ -369,7 +378,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
const FHyperTwistTrainingSessionTemplate& PeerTemplate,
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* PeerStats,
|
||||
const EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind AnalyticsSupportKind,
|
||||
const bool bUsedTemplateSignalConfidenceSnapshotBias = false
|
||||
const bool bUsedTemplateSignalSupportBias = false
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingTemplateLaunchSelectionProvenance Provenance;
|
||||
|
|
@ -417,21 +426,23 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
}
|
||||
else
|
||||
{
|
||||
Provenance.TemplateSignalSupportKind = bUsedTemplateSignalConfidenceSnapshotBias
|
||||
Provenance.TemplateSignalSupportKind = bUsedTemplateSignalSupportBias
|
||||
? EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportKind::
|
||||
ConfidenceLaneBias
|
||||
: EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportKind::
|
||||
BroaderOutcomeOnly;
|
||||
Provenance.TemplateSignalSupportBiasSnapshot =
|
||||
BuildTemplateLaunchTemplateSignalSupportBiasSnapshot(SelectedStats);
|
||||
Provenance.ComparablePeerConfidenceSnapshot =
|
||||
BuildTemplateLaunchComparablePeerConfidenceSnapshot(SelectedStats);
|
||||
const FString SelectedComparablePeerConfidenceAuditClause =
|
||||
BuildTemplateLaunchComparablePeerConfidenceAuditClause(
|
||||
SelectedStats,
|
||||
TEXT("chosen template"));
|
||||
if (bUsedTemplateSignalConfidenceSnapshotBias)
|
||||
if (bUsedTemplateSignalSupportBias)
|
||||
{
|
||||
Provenance.DecisionSummaryLine = FString::Printf(
|
||||
TEXT("Selector: tied with %s on primary dashboard priority; analytics preferred %s on broader template-scoped outcome signal with retained confidence-lane bias support: %s | chosen %s | peer %s."),
|
||||
TEXT("Selector: tied with %s on primary dashboard priority; analytics preferred %s on broader template-scoped outcome signal with retained confidence-lane support-bias reinforcement: %s | chosen %s | peer %s."),
|
||||
*ResolveDashboardTemplateLaunchDisplayTitle(PeerTemplate),
|
||||
*ResolveDashboardTemplateLaunchDisplayTitle(SelectedTemplate),
|
||||
*SelectedComparablePeerConfidenceAuditClause,
|
||||
|
|
@ -442,7 +453,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
else
|
||||
{
|
||||
Provenance.DecisionSummaryLine = FString::Printf(
|
||||
TEXT("Selector: tied with %s on primary dashboard priority; analytics preferred %s on broader template-scoped outcome signal without selector-split confidence support or retained confidence-lane bias support: %s | chosen %s | peer %s."),
|
||||
TEXT("Selector: tied with %s on primary dashboard priority; analytics preferred %s on broader template-scoped outcome signal without support-bias reinforcement deciding the winner: %s | chosen %s | peer %s."),
|
||||
*ResolveDashboardTemplateLaunchDisplayTitle(PeerTemplate),
|
||||
*ResolveDashboardTemplateLaunchDisplayTitle(SelectedTemplate),
|
||||
*SelectedComparablePeerConfidenceAuditClause,
|
||||
|
|
@ -955,6 +966,23 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
return Snapshot;
|
||||
}
|
||||
|
||||
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot
|
||||
BuildTemplateLaunchTemplateSignalSupportBiasSnapshot(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot Snapshot;
|
||||
const bool bBiasEarned = HasTemplateLaunchTemplateSignalSupportBias(
|
||||
TemplateStats,
|
||||
&Snapshot.ConfidenceLaneBiasOutcomeRuns,
|
||||
&Snapshot.BroaderOutcomeOnlyOutcomeRuns
|
||||
);
|
||||
Snapshot.State = bBiasEarned
|
||||
? EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState::Earned
|
||||
: EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState::Suppressed;
|
||||
return Snapshot;
|
||||
}
|
||||
|
||||
FString BuildTemplateLaunchComparablePeerConfidenceStatusClauseFromSnapshot(
|
||||
const FHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshot& Snapshot
|
||||
)
|
||||
|
|
@ -1076,6 +1104,46 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
);
|
||||
}
|
||||
|
||||
FString BuildTemplateLaunchSelectionTemplateSignalSupportBiasDetailFragment(
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
|
||||
)
|
||||
{
|
||||
if (SelectionProvenance == nullptr
|
||||
|| SelectionProvenance->ReasonClass
|
||||
!= EHyperTwistTrainingTemplateLaunchSelectionReasonClass::AnalyticsTieBreak
|
||||
|| SelectionProvenance->AnalyticsSupportKind
|
||||
!= EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind::
|
||||
TemplateScopedOutcomeSignal
|
||||
|| !SelectionProvenance->TemplateSignalSupportBiasSnapshot.IsStructurallyValid())
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
const FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot& Snapshot =
|
||||
SelectionProvenance->TemplateSignalSupportBiasSnapshot;
|
||||
switch (Snapshot.State)
|
||||
{
|
||||
case EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState::Earned:
|
||||
return FString::Printf(
|
||||
TEXT(
|
||||
" | at-launch support-bias earned on confidence-lane-bias history (%d bias outcomes vs %d broader outcomes)"),
|
||||
Snapshot.ConfidenceLaneBiasOutcomeRuns,
|
||||
Snapshot.BroaderOutcomeOnlyOutcomeRuns
|
||||
);
|
||||
case EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState::
|
||||
Suppressed:
|
||||
return FString::Printf(
|
||||
TEXT(
|
||||
" | at-launch support-bias suppressed (%d bias outcomes vs %d broader outcomes)"),
|
||||
Snapshot.ConfidenceLaneBiasOutcomeRuns,
|
||||
Snapshot.BroaderOutcomeOnlyOutcomeRuns
|
||||
);
|
||||
case EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState::None:
|
||||
default:
|
||||
return FString();
|
||||
}
|
||||
}
|
||||
|
||||
FString BuildTemplateLaunchSelectionComparablePeerConfidenceDetailFragment(
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
|
||||
)
|
||||
|
|
@ -1142,6 +1210,9 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
const FString TemplateSignalSupportDetailFragment =
|
||||
BuildTemplateLaunchSelectionTemplateSignalSupportDetailFragment(
|
||||
SelectionProvenance);
|
||||
const FString TemplateSignalSupportBiasDetailFragment =
|
||||
BuildTemplateLaunchSelectionTemplateSignalSupportBiasDetailFragment(
|
||||
SelectionProvenance);
|
||||
const FString PeerSupportDispositionDetailFragment =
|
||||
BuildTemplateLaunchSelectionPeerSupportDispositionDetailFragment(SelectionProvenance);
|
||||
const FString ComparablePeerConfidenceDetailFragment =
|
||||
|
|
@ -1149,6 +1220,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
SelectionProvenance);
|
||||
const FString SelectionReasonDetailFragment =
|
||||
AnalyticsSupportDetailFragment + TemplateSignalSupportDetailFragment
|
||||
+ TemplateSignalSupportBiasDetailFragment
|
||||
+ PeerSupportDispositionDetailFragment
|
||||
+ ComparablePeerConfidenceDetailFragment;
|
||||
if (!SelectionProvenance->PeerTemplateTitle.IsEmpty()
|
||||
|
|
@ -2029,7 +2101,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
bool bPreferCandidate = false;
|
||||
EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind CandidateAnalyticsSupportKind =
|
||||
EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind::None;
|
||||
bool bCandidateUsedTemplateSignalConfidenceSnapshotBias = false;
|
||||
bool bCandidateUsedTemplateSignalSupportBias = false;
|
||||
};
|
||||
|
||||
FTemplateLaunchAnalyticsPreferenceDecision ResolveTemplateAnalyticsPreferenceDecision(
|
||||
|
|
@ -2082,7 +2154,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
Decision.CandidateAnalyticsSupportKind =
|
||||
EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind::
|
||||
TemplateScopedOutcomeSignal;
|
||||
Decision.bCandidateUsedTemplateSignalConfidenceSnapshotBias = true;
|
||||
Decision.bCandidateUsedTemplateSignalSupportBias = true;
|
||||
}
|
||||
return Decision;
|
||||
}
|
||||
|
|
@ -8835,7 +8907,7 @@ const FHyperTwistTrainingSessionTemplate* UHyperTwistCoachDashboardWidget::FindP
|
|||
PreviousPreferredTemplate,
|
||||
PreferredStats,
|
||||
AnalyticsDecision.CandidateAnalyticsSupportKind,
|
||||
AnalyticsDecision.bCandidateUsedTemplateSignalConfidenceSnapshotBias
|
||||
AnalyticsDecision.bCandidateUsedTemplateSignalSupportBias
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1082,6 +1082,14 @@ enum class EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportKind :
|
|||
ConfidenceLaneBias UMETA(DisplayName = "Confidence Lane Bias")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Earned UMETA(DisplayName = "Earned"),
|
||||
Suppressed UMETA(DisplayName = "Suppressed")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshotState : uint8
|
||||
{
|
||||
|
|
@ -1092,6 +1100,27 @@ enum class EHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshotStat
|
|||
SuppressedPeerNoEvidenceHeavy UMETA(DisplayName = "Suppressed Peer No Evidence Heavy")
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState State =
|
||||
EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 ConfidenceLaneBiasOutcomeRuns = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
int32 BroaderOutcomeOnlyOutcomeRuns = 0;
|
||||
|
||||
bool IsStructurallyValid() const
|
||||
{
|
||||
return State != EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState::None;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshot
|
||||
{
|
||||
|
|
@ -1145,6 +1174,10 @@ struct FHyperTwistTrainingTemplateLaunchSelectionProvenance
|
|||
TemplateSignalSupportKind =
|
||||
EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportKind::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot
|
||||
TemplateSignalSupportBiasSnapshot;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshot
|
||||
ComparablePeerConfidenceSnapshot;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
# HyperTwist Phase 4 template-signal support-bias snapshot provenance packet
|
||||
|
||||
## Purpose
|
||||
|
||||
This packet persists the broader template-signal `support-bias earned/suppressed` state into template selection provenance at launch time. That keeps later audits honest: template history, recap, and other selector-detail surfaces now read the stored at-launch support-bias posture instead of inferring it from later analytics drift.
|
||||
|
||||
## Scope
|
||||
|
||||
- add a compact template-signal support-bias snapshot under template selection provenance
|
||||
- capture:
|
||||
- whether support-bias was `earned` or `suppressed` at launch
|
||||
- the chosen template's retained `confidence-lane-bias` outcome count
|
||||
- the chosen template's retained `broader-outcome-only` outcome count
|
||||
- stamp that snapshot whenever the dashboard records a broader `TemplateScopedOutcomeSignal` analytics tie-break launch
|
||||
- append the stored `at-launch support-bias` fragment through the shared selector-detail formatter used by live detail, template history, and recap
|
||||
- correct broader-outcome decision-summary wording so it no longer claims the chosen template lacked retained support-bias when that bias simply did not decide the winner
|
||||
|
||||
## What landed
|
||||
|
||||
- `HyperTwistTrainingTypes.h`
|
||||
- added `EHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshotState`
|
||||
- added `FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot`
|
||||
- nested `TemplateSignalSupportBiasSnapshot` under `FHyperTwistTrainingTemplateLaunchSelectionProvenance`
|
||||
- `HyperTwistCoachDashboardWidget.cpp`
|
||||
- added `BuildTemplateLaunchTemplateSignalSupportBiasSnapshot(...)`
|
||||
- broader analytics provenance now stamps the selected template's support-bias snapshot at launch
|
||||
- added shared selector-detail rendering for:
|
||||
- `at-launch support-bias earned`
|
||||
- `at-launch support-bias suppressed`
|
||||
- renamed the local broader-analytics decision flag from the stale confidence-snapshot name to the actual support-bias meaning
|
||||
- broader-outcome decision-summary text now says the winner launched without support-bias reinforcement deciding the outcome, rather than claiming the chosen template lacked retained support-bias entirely
|
||||
|
||||
## Product effect
|
||||
|
||||
- template history and recap now preserve the dashboard's at-launch support-bias posture for broader analytics launches
|
||||
- selector-detail audits can distinguish:
|
||||
- what kind of broader template-signal support actually decided the winner
|
||||
- versus whether support-bias was merely present or suppressed at launch
|
||||
- stored decision summaries no longer overstate the absence of retained support-bias when it existed but did not change the winner
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- broader `TemplateScopedOutcomeSignal` launch provenance persists an `earned/suppressed` support-bias snapshot with both retained outcome counts
|
||||
- shared selector detail shows the stored at-launch support-bias fragment in live detail, template history, and recap
|
||||
- older runs without the new snapshot keep rendering without fabricated support-bias detail
|
||||
- broader-outcome decision summaries avoid claiming the chosen template lacked retained support-bias when that state was simply non-decisive
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. full `Development Editor|Win64` build succeeds
|
||||
2. confirm broader analytics provenance stamps `TemplateSignalSupportBiasSnapshot`
|
||||
3. confirm shared selector detail renders stored `at-launch support-bias earned/suppressed`
|
||||
4. confirm broader-outcome decision summaries use the corrected non-decisive wording
|
||||
Loading…
Add table
Reference in a new issue