Persist template decision-bias snapshot provenance

This commit is contained in:
axiomlogicnexus 2026-05-07 15:31:45 +02:00
parent 06b88284e9
commit dc93432f76
3 changed files with 155 additions and 0 deletions

View file

@ -151,6 +151,11 @@ namespace HyperTwistCoachDashboardWidgetInternal
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
);
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot
BuildTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot(
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
);
FString BuildTemplateLaunchComparablePeerConfidenceAuditClause(
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats,
const TCHAR* SubjectLabel
@ -173,6 +178,10 @@ namespace HyperTwistCoachDashboardWidgetInternal
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
);
FString BuildTemplateLaunchSelectionTemplateSignalSupportDecisionBiasSnapshotDetailFragment(
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
);
bool HasTemplateLaunchComparablePeerEvidenceForConfidenceBonus(
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats,
int32* OutComparablePeerOutcomeRuns = nullptr,
@ -502,6 +511,8 @@ namespace HyperTwistCoachDashboardWidgetInternal
None;
Provenance.TemplateSignalSupportBiasSnapshot =
BuildTemplateLaunchTemplateSignalSupportBiasSnapshot(SelectedStats);
Provenance.TemplateSignalSupportDecisionBiasSnapshot =
BuildTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot(SelectedStats);
Provenance.ComparablePeerConfidenceSnapshot =
BuildTemplateLaunchComparablePeerConfidenceSnapshot(SelectedStats);
const FString SelectedComparablePeerConfidenceAuditClause =
@ -1217,6 +1228,25 @@ namespace HyperTwistCoachDashboardWidgetInternal
return Snapshot;
}
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot
BuildTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot(
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
)
{
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot Snapshot;
const bool bBiasEarned = HasTemplateLaunchTemplateSignalSupportDecisionBias(
TemplateStats,
&Snapshot.DecisionSplitGuardOutcomeRuns,
&Snapshot.PlainSnapshotGuardOutcomeRuns
);
Snapshot.State = bBiasEarned
? EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState::
Earned
: EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState::
Suppressed;
return Snapshot;
}
FString BuildTemplateLaunchComparablePeerConfidenceStatusClauseFromSnapshot(
const FHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshot& Snapshot
)
@ -1425,6 +1455,49 @@ namespace HyperTwistCoachDashboardWidgetInternal
}
}
FString BuildTemplateLaunchSelectionTemplateSignalSupportDecisionBiasSnapshotDetailFragment(
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
)
{
if (SelectionProvenance == nullptr
|| SelectionProvenance->ReasonClass
!= EHyperTwistTrainingTemplateLaunchSelectionReasonClass::AnalyticsTieBreak
|| SelectionProvenance->AnalyticsSupportKind
!= EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind::
TemplateScopedOutcomeSignal
|| !SelectionProvenance->TemplateSignalSupportDecisionBiasSnapshot
.IsStructurallyValid())
{
return FString();
}
const FHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot&
Snapshot = SelectionProvenance->TemplateSignalSupportDecisionBiasSnapshot;
switch (Snapshot.State)
{
case EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState::
Earned:
return FString::Printf(
TEXT(
" | at-launch decision-bias earned on reinforced snapshot-guard history (%d reinforced outcomes vs %d plain outcomes)"),
Snapshot.DecisionSplitGuardOutcomeRuns,
Snapshot.PlainSnapshotGuardOutcomeRuns
);
case EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState::
Suppressed:
return FString::Printf(
TEXT(
" | at-launch decision-bias suppressed (%d reinforced outcomes vs %d plain outcomes)"),
Snapshot.DecisionSplitGuardOutcomeRuns,
Snapshot.PlainSnapshotGuardOutcomeRuns
);
case EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState::
None:
default:
return FString();
}
}
FString BuildTemplateLaunchSelectionComparablePeerConfidenceDetailFragment(
const FHyperTwistTrainingTemplateLaunchSelectionProvenance* SelectionProvenance
)
@ -1497,6 +1570,9 @@ namespace HyperTwistCoachDashboardWidgetInternal
const FString TemplateSignalSupportDecisionBiasDetailFragment =
BuildTemplateLaunchSelectionTemplateSignalSupportDecisionBiasDetailFragment(
SelectionProvenance);
const FString TemplateSignalSupportDecisionBiasSnapshotDetailFragment =
BuildTemplateLaunchSelectionTemplateSignalSupportDecisionBiasSnapshotDetailFragment(
SelectionProvenance);
const FString TemplateSignalSupportBiasDetailFragment =
BuildTemplateLaunchSelectionTemplateSignalSupportBiasDetailFragment(
SelectionProvenance);
@ -1509,6 +1585,7 @@ namespace HyperTwistCoachDashboardWidgetInternal
AnalyticsSupportDetailFragment + TemplateSignalSupportDetailFragment
+ TemplateSignalSupportDecisionDetailFragment
+ TemplateSignalSupportDecisionBiasDetailFragment
+ TemplateSignalSupportDecisionBiasSnapshotDetailFragment
+ TemplateSignalSupportBiasDetailFragment
+ PeerSupportDispositionDetailFragment
+ ComparablePeerConfidenceDetailFragment;

View file

@ -1105,6 +1105,15 @@ enum class EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisi
DecisionSplitGuard UMETA(DisplayName = "Decision Split Guard")
};
UENUM(BlueprintType)
enum class EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState :
uint8
{
None UMETA(DisplayName = "None"),
Earned UMETA(DisplayName = "Earned"),
Suppressed UMETA(DisplayName = "Suppressed")
};
UENUM(BlueprintType)
enum class EHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshotState : uint8
{
@ -1163,6 +1172,29 @@ struct FHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshot
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState State =
EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState::None;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 DecisionSplitGuardOutcomeRuns = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 PlainSnapshotGuardOutcomeRuns = 0;
bool IsStructurallyValid() const
{
return State
!= EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState::
None;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistTrainingTemplateLaunchSelectionProvenance
{
@ -1203,6 +1235,10 @@ struct FHyperTwistTrainingTemplateLaunchSelectionProvenance
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportBiasSnapshot
TemplateSignalSupportBiasSnapshot;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot
TemplateSignalSupportDecisionBiasSnapshot;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FHyperTwistTrainingTemplateLaunchComparablePeerConfidenceSnapshot
ComparablePeerConfidenceSnapshot;

View file

@ -0,0 +1,42 @@
# HyperTwist Phase 4 template-signal decision-bias snapshot provenance packet
## Purpose
This packet stops template launch history and recap from recomputing the stricter template-signal decision-bias guard from whatever reinforced-vs-plain snapshot-guard analytics happen to exist later. It stores the dashboard's at-launch `decision-bias earned/suppressed` state directly in template selection provenance and reuses that retained snapshot when rendering selector detail.
## Scope
- add a persisted template-signal decision-bias snapshot to launch selection provenance
- stamp that snapshot whenever a broader `TemplateScopedOutcomeSignal` analytics tie-break builds selection provenance
- append the stored at-launch decision-bias snapshot to the shared selector-detail path used by dashboard template history and template-backed recap
## What landed
- `HyperTwistTrainingTypes.h`
- added `EHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshotState`
- added `FHyperTwistTrainingTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot`
- added `TemplateSignalSupportDecisionBiasSnapshot` to `FHyperTwistTrainingTemplateLaunchSelectionProvenance`
- `HyperTwistCoachDashboardWidget.cpp`
- added `BuildTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot(...)`
- broader analytics selection provenance now stamps the current `decision-bias earned/suppressed` state with reinforced and plain snapshot-guard outcome counts
- shared selector detail now renders:
- `at-launch decision-bias earned ...`
- or `at-launch decision-bias suppressed ...`
## Product effect
- template launch history and recap now preserve the dashboard's at-launch decision-bias posture instead of drifting with later reinforced-vs-plain snapshot-guard analytics
- selector audits can distinguish the persisted at-launch decision-bias state from the separately persisted `DecisionSplitGuard` winner-reason flag
## Acceptance criteria
- broader `TemplateScopedOutcomeSignal` selection provenance stores an at-launch decision-bias snapshot
- template launch history and recap read that stored snapshot back through shared selector detail
- the new selector detail uses retained reinforced vs plain snapshot-guard counts instead of recomputing them from current analytics
## Validation checklist
1. full `Development Editor|Win64` build succeeds
2. confirm `FHyperTwistTrainingTemplateLaunchSelectionProvenance` persists `TemplateSignalSupportDecisionBiasSnapshot`
3. confirm broader analytics provenance stamping calls `BuildTemplateLaunchTemplateSignalSupportDecisionBiasSnapshot(...)`
4. confirm shared selector detail shows `at-launch decision-bias earned ...` or `at-launch decision-bias suppressed ...`