Persist template-signal decision-bias provenance
This commit is contained in:
parent
493da3b30a
commit
23ff059aca
3 changed files with 142 additions and 6 deletions
|
|
@ -355,6 +355,22 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
}
|
||||
}
|
||||
|
||||
FString ResolveTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKindLabel(
|
||||
const EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind
|
||||
TemplateSignalSupportDecisionBiasKind
|
||||
)
|
||||
{
|
||||
switch (TemplateSignalSupportDecisionBiasKind)
|
||||
{
|
||||
case EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind::
|
||||
DecisionSplitGuard:
|
||||
return TEXT("decision-split-guard");
|
||||
case EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind::None:
|
||||
default:
|
||||
return TEXT("none");
|
||||
}
|
||||
}
|
||||
|
||||
FString ResolveTemplateLaunchSelectionPeerSupportKindDispositionLabel(
|
||||
const EHyperTwistTrainingTemplateLaunchSelectionPeerSupportKindDisposition
|
||||
PeerSupportKindDisposition
|
||||
|
|
@ -418,7 +434,8 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
const FHyperTwistTrainingSessionTemplate& PeerTemplate,
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* PeerStats,
|
||||
const EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind AnalyticsSupportKind,
|
||||
const bool bUsedTemplateSignalSupportBiasSnapshotGuard = false
|
||||
const bool bUsedTemplateSignalSupportBiasSnapshotGuard = false,
|
||||
const bool bUsedTemplateSignalSupportDecisionBiasGuard = false
|
||||
)
|
||||
{
|
||||
FHyperTwistTrainingTemplateLaunchSelectionProvenance Provenance;
|
||||
|
|
@ -477,6 +494,12 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
SupportBiasSnapshotGuard
|
||||
: EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionKind::
|
||||
None;
|
||||
Provenance.TemplateSignalSupportDecisionBiasKind =
|
||||
bUsedTemplateSignalSupportDecisionBiasGuard
|
||||
? EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind::
|
||||
DecisionSplitGuard
|
||||
: EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind::
|
||||
None;
|
||||
Provenance.TemplateSignalSupportBiasSnapshot =
|
||||
BuildTemplateLaunchTemplateSignalSupportBiasSnapshot(SelectedStats);
|
||||
Provenance.ComparablePeerConfidenceSnapshot =
|
||||
|
|
@ -485,7 +508,18 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
BuildTemplateLaunchComparablePeerConfidenceAuditClause(
|
||||
SelectedStats,
|
||||
TEXT("chosen template"));
|
||||
if (bUsedTemplateSignalSupportBiasSnapshotGuard)
|
||||
if (bUsedTemplateSignalSupportDecisionBiasGuard)
|
||||
{
|
||||
Provenance.DecisionSummaryLine = FString::Printf(
|
||||
TEXT("Selector: tied with %s on primary dashboard priority; analytics preferred %s on broader template-scoped outcome signal with earned-vs-non-earned support-bias snapshot guard reinforcement, with the decision-split guard specifically breaking the remaining tie: %s | chosen %s | peer %s."),
|
||||
*ResolveDashboardTemplateLaunchDisplayTitle(PeerTemplate),
|
||||
*ResolveDashboardTemplateLaunchDisplayTitle(SelectedTemplate),
|
||||
*SelectedComparablePeerConfidenceAuditClause,
|
||||
*BuildTemplateLaunchAnalyticsTieBreakSignalFragment(SelectedStats),
|
||||
*BuildTemplateLaunchAnalyticsTieBreakSignalFragment(PeerStats)
|
||||
);
|
||||
}
|
||||
else if (bUsedTemplateSignalSupportBiasSnapshotGuard)
|
||||
{
|
||||
Provenance.DecisionSummaryLine = FString::Printf(
|
||||
TEXT("Selector: tied with %s on primary dashboard priority; analytics preferred %s on broader template-scoped outcome signal with earned-vs-non-earned support-bias snapshot guard reinforcement deciding the winner: %s | chosen %s | peer %s."),
|
||||
|
|
@ -1297,6 +1331,30 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
);
|
||||
}
|
||||
|
||||
FString BuildTemplateLaunchSelectionTemplateSignalSupportDecisionBiasDetailFragment(
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
|
||||
)
|
||||
{
|
||||
if (SelectionProvenance == nullptr
|
||||
|| SelectionProvenance->ReasonClass
|
||||
!= EHyperTwistTrainingTemplateLaunchSelectionReasonClass::AnalyticsTieBreak
|
||||
|| SelectionProvenance->AnalyticsSupportKind
|
||||
!= EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind::
|
||||
TemplateScopedOutcomeSignal
|
||||
|| SelectionProvenance->TemplateSignalSupportDecisionBiasKind
|
||||
== EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind::
|
||||
None)
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
return FString::Printf(
|
||||
TEXT(" | template-signal decision-bias %s"),
|
||||
*ResolveTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKindLabel(
|
||||
SelectionProvenance->TemplateSignalSupportDecisionBiasKind)
|
||||
);
|
||||
}
|
||||
|
||||
FString BuildTemplateLaunchSelectionTemplateSignalSupportBiasDetailFragment(
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
|
||||
)
|
||||
|
|
@ -1406,6 +1464,9 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
const FString TemplateSignalSupportDecisionDetailFragment =
|
||||
BuildTemplateLaunchSelectionTemplateSignalSupportDecisionDetailFragment(
|
||||
SelectionProvenance);
|
||||
const FString TemplateSignalSupportDecisionBiasDetailFragment =
|
||||
BuildTemplateLaunchSelectionTemplateSignalSupportDecisionBiasDetailFragment(
|
||||
SelectionProvenance);
|
||||
const FString TemplateSignalSupportBiasDetailFragment =
|
||||
BuildTemplateLaunchSelectionTemplateSignalSupportBiasDetailFragment(
|
||||
SelectionProvenance);
|
||||
|
|
@ -1417,6 +1478,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
const FString SelectionReasonDetailFragment =
|
||||
AnalyticsSupportDetailFragment + TemplateSignalSupportDetailFragment
|
||||
+ TemplateSignalSupportDecisionDetailFragment
|
||||
+ TemplateSignalSupportDecisionBiasDetailFragment
|
||||
+ TemplateSignalSupportBiasDetailFragment
|
||||
+ PeerSupportDispositionDetailFragment
|
||||
+ ComparablePeerConfidenceDetailFragment;
|
||||
|
|
@ -2482,6 +2544,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind CandidateAnalyticsSupportKind =
|
||||
EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind::None;
|
||||
bool bCandidateUsedTemplateSignalSupportBiasSnapshotGuard = false;
|
||||
bool bCandidateUsedTemplateSignalSupportDecisionBiasGuard = false;
|
||||
};
|
||||
|
||||
FTemplateLaunchAnalyticsPreferenceDecision ResolveTemplateAnalyticsPreferenceDecision(
|
||||
|
|
@ -2519,15 +2582,23 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
}
|
||||
return Decision;
|
||||
}
|
||||
const int32 CandidateTemplateSignalSupportBiasBonus =
|
||||
const int32 CandidateTemplateSignalSupportBiasSnapshotGuardBonus =
|
||||
HasTemplateLaunchTemplateSignalSupportBias(CandidateStats)
|
||||
&& HasTemplateLaunchTemplateSignalSupportBiasSnapshotBias(CandidateStats)
|
||||
? 1
|
||||
: 0;
|
||||
const int32 IncumbentTemplateSignalSupportBiasSnapshotGuardBonus =
|
||||
HasTemplateLaunchTemplateSignalSupportBias(IncumbentStats)
|
||||
&& HasTemplateLaunchTemplateSignalSupportBiasSnapshotBias(IncumbentStats)
|
||||
? 1
|
||||
: 0;
|
||||
const int32 CandidateTemplateSignalSupportBiasBonus =
|
||||
CandidateTemplateSignalSupportBiasSnapshotGuardBonus > 0
|
||||
&& HasTemplateLaunchTemplateSignalSupportDecisionBias(CandidateStats)
|
||||
? 1
|
||||
: 0;
|
||||
const int32 IncumbentTemplateSignalSupportBiasBonus =
|
||||
HasTemplateLaunchTemplateSignalSupportBias(IncumbentStats)
|
||||
&& HasTemplateLaunchTemplateSignalSupportBiasSnapshotBias(IncumbentStats)
|
||||
IncumbentTemplateSignalSupportBiasSnapshotGuardBonus > 0
|
||||
&& HasTemplateLaunchTemplateSignalSupportDecisionBias(IncumbentStats)
|
||||
? 1
|
||||
: 0;
|
||||
|
|
@ -2543,6 +2614,9 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind::
|
||||
TemplateScopedOutcomeSignal;
|
||||
Decision.bCandidateUsedTemplateSignalSupportBiasSnapshotGuard = true;
|
||||
Decision.bCandidateUsedTemplateSignalSupportDecisionBiasGuard =
|
||||
CandidateTemplateSignalSupportBiasSnapshotGuardBonus
|
||||
== IncumbentTemplateSignalSupportBiasSnapshotGuardBonus;
|
||||
}
|
||||
return Decision;
|
||||
}
|
||||
|
|
@ -9296,7 +9370,9 @@ const FHyperTwistTrainingSessionTemplate* UHyperTwistCoachDashboardWidget::FindP
|
|||
PreferredStats,
|
||||
AnalyticsDecision.CandidateAnalyticsSupportKind,
|
||||
AnalyticsDecision
|
||||
.bCandidateUsedTemplateSignalSupportBiasSnapshotGuard
|
||||
.bCandidateUsedTemplateSignalSupportBiasSnapshotGuard,
|
||||
AnalyticsDecision
|
||||
.bCandidateUsedTemplateSignalSupportDecisionBiasGuard
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1097,6 +1097,14 @@ enum class EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisi
|
|||
SupportBiasSnapshotGuard UMETA(DisplayName = "Support Bias Snapshot Guard")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind :
|
||||
uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
DecisionSplitGuard UMETA(DisplayName = "Decision Split Guard")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshotState : uint8
|
||||
{
|
||||
|
|
@ -1186,6 +1194,11 @@ struct FHyperTwistTrainingTemplateLaunchSelectionProvenance
|
|||
TemplateSignalSupportDecisionKind =
|
||||
EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionKind::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind
|
||||
TemplateSignalSupportDecisionBiasKind =
|
||||
EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind::None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
|
||||
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot
|
||||
TemplateSignalSupportBiasSnapshot;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
# HyperTwist Phase 4 template-signal decision-bias provenance packet
|
||||
|
||||
## Purpose
|
||||
|
||||
This packet persists when the new decision-split guard is what actually changes a tied broader template-signal winner. That keeps selector audits precise: dashboard detail, template history, and recap can now distinguish plain `SupportBiasSnapshotGuard` wins from wins that were specifically reinforced by the stricter decision-split guard.
|
||||
|
||||
## Scope
|
||||
|
||||
- add a compact template-signal decision-bias enum under template launch selection provenance
|
||||
- stamp that field only when the stricter decision-split guard is what separates two otherwise equal snapshot-guard candidates
|
||||
- update broader template-signal decision summary wording so it explicitly names the decision-split guard when it specifically breaks the remaining tie
|
||||
- append the stored decision-bias marker through the shared selector-detail formatter used by live detail, template history, and recap
|
||||
|
||||
## What landed
|
||||
|
||||
- `HyperTwistTrainingTypes.h`
|
||||
- added `EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKind`
|
||||
- nested `TemplateSignalSupportDecisionBiasKind` under `FHyperTwistTrainingTemplateLaunchSelectionProvenance`
|
||||
- `HyperTwistCoachDashboardWidget.cpp`
|
||||
- added `ResolveTemplateLaunchSelectionTemplateSignalSupportDecisionBiasKindLabel(...)`
|
||||
- broader analytics provenance now stamps:
|
||||
- `DecisionSplitGuard` when the stricter decision-split guard specifically breaks the remaining tie between snapshot-guard candidates
|
||||
- broader analytics decision summaries now explicitly call out that decision-split guard when it changes the winner
|
||||
- shared selector detail now appends `template-signal decision-bias decision-split-guard` for runs that were specifically reinforced by the new guard
|
||||
- widened the analytics tie-break decision struct so the winner path can distinguish:
|
||||
- plain `SupportBiasSnapshotGuard` wins
|
||||
- `SupportBiasSnapshotGuard` wins that required the stricter decision-split guard
|
||||
|
||||
## Product effect
|
||||
|
||||
- live `[Template Launch]` detail now explicitly shows when a broader template-signal winner was not just a plain snapshot-guard win, but one specifically reinforced by the decision-split guard
|
||||
- template history and recap preserve that same distinction from stored provenance
|
||||
- plain snapshot-guard wins remain distinguishable because they do not show the new decision-bias detail
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- broader template-signal selection provenance persists a distinct decision-bias kind when the decision-split guard changes the winner
|
||||
- shared selector detail shows that stored decision-bias kind in live detail, template history, and recap
|
||||
- broader analytics decision summaries explicitly mention when the decision-split guard specifically breaks the remaining tie
|
||||
- plain `SupportBiasSnapshotGuard` wins continue to render without fabricated decision-split reinforcement claims
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. full `Development Editor|Win64` build succeeds
|
||||
2. confirm broader analytics provenance stamps `TemplateSignalSupportDecisionBiasKind = DecisionSplitGuard` only when the stricter decision-split guard changes the winner
|
||||
3. confirm shared selector detail shows `template-signal decision-bias decision-split-guard`
|
||||
4. confirm plain snapshot-guard wins continue to render without the new decision-bias detail
|
||||
Loading…
Add table
Reference in a new issue