Split template analytics by decision-bias snapshot guard

This commit is contained in:
axiomlogicnexus 2026-05-07 16:34:08 +02:00
parent 167b551a69
commit 3f049de253
4 changed files with 119 additions and 0 deletions

View file

@ -959,6 +959,37 @@ namespace HyperTwistCoachDashboardWidgetInternal
);
}
}
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats& PlainDecisionSplitGuardStats =
TemplateStats
->DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardPlainStats;
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats&
DecisionBiasSnapshotGuardStats =
TemplateStats
->DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardDecisionBiasSnapshotGuardStats;
if (PlainDecisionSplitGuardStats.IsStructurallyValid()
|| DecisionBiasSnapshotGuardStats.IsStructurallyValid())
{
Fragment += FString::Printf(
TEXT(" | %s | %s"),
*BuildTemplateLaunchSelectionLaneAnalyticsSummary(
PlainDecisionSplitGuardStats,
TEXT("plain-decision-split-guard")),
*BuildTemplateLaunchSelectionLaneAnalyticsSummary(
DecisionBiasSnapshotGuardStats,
TEXT("decision-bias-snapshot-guard"))
);
if (PlainDecisionSplitGuardStats.GetOutcomeRunCount() > 0
&& DecisionBiasSnapshotGuardStats.GetOutcomeRunCount() > 0)
{
Fragment += FString::Printf(
TEXT(" | snapshot-guarded-minus-plain-decision-split delta success %+.2f | delta mistakes %+.2f"),
DecisionBiasSnapshotGuardStats.OverallSuccessRate
- PlainDecisionSplitGuardStats.OverallSuccessRate,
DecisionBiasSnapshotGuardStats.AverageMistakesPerOutcomeRun
- PlainDecisionSplitGuardStats.AverageMistakesPerOutcomeRun
);
}
}
return Fragment;
}

View file

@ -9174,6 +9174,10 @@ UHyperTwistTrainingRepositoryLibrary::ListTemplateLaunchScopedStatsForUser(
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardNoDecisionBiasAccumulator;
FSelectionScopedAccumulator
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardAccumulator;
FSelectionScopedAccumulator
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardPlainAccumulator;
FSelectionScopedAccumulator
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardDecisionBiasSnapshotGuardAccumulator;
FSelectionScopedAccumulator
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotEarnedAccumulator;
FSelectionScopedAccumulator
@ -9391,6 +9395,26 @@ UHyperTwistTrainingRepositoryLibrary::ListTemplateLaunchScopedStatsForUser(
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardAccumulator,
Provenance.SelectionProvenance
);
if (Provenance.SelectionProvenance
.TemplateSignalSupportDecisionBiasSnapshotDecisionKind
==
EHyperTwistTrainingTemplateLaunchSelectionTemplateSignalSupportDecisionBiasSnapshotDecisionKind::
DecisionBiasSnapshotGuard)
{
AccumulateSelectionScopedStats(
Accumulator
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardDecisionBiasSnapshotGuardAccumulator,
Provenance.SelectionProvenance
);
}
else
{
AccumulateSelectionScopedStats(
Accumulator
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardPlainAccumulator,
Provenance.SelectionProvenance
);
}
}
else
{
@ -9794,6 +9818,16 @@ UHyperTwistTrainingRepositoryLibrary::ListTemplateLaunchScopedStatsForUser(
Accumulator
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardAccumulator
.Stats;
Accumulator.Stats
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardPlainStats =
Accumulator
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardPlainAccumulator
.Stats;
Accumulator.Stats
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardDecisionBiasSnapshotGuardStats =
Accumulator
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardDecisionBiasSnapshotGuardAccumulator
.Stats;
Accumulator.Stats
.DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotEarnedStats =
Accumulator

View file

@ -2391,6 +2391,14 @@ struct FHyperTwistTrainingTemplateLaunchScopedStats
FHyperTwistTrainingTemplateLaunchSelectionScopedStats
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardStats;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FHyperTwistTrainingTemplateLaunchSelectionScopedStats
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardPlainStats;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FHyperTwistTrainingTemplateLaunchSelectionScopedStats
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardDecisionBiasSnapshotGuardStats;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FHyperTwistTrainingTemplateLaunchSelectionScopedStats
DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotEarnedStats;

View file

@ -0,0 +1,46 @@
# HyperTwist Phase 4 template-signal decision-bias snapshot guard analytics packet
## Purpose
This packet aggregates the newly persisted historical decision-bias snapshot guard provenance back into repo-backed template analytics. The dashboard can now compare plain `DecisionSplitGuard` launches against the subset where earned-vs-non-earned decision-bias snapshot history became the final winner instead of treating every decision-split win as the same lane.
## Scope
- add repo-backed template-scoped stats buckets for `DecisionSplitGuard` launches with and without the persisted `DecisionBiasSnapshotGuard` marker
- route stored `TemplateSignalSupportDecisionBiasSnapshotDecisionKind` through template launch scoped analytics derivation
- extend the shared `template-signal decision` analytics fragment so live dashboard detail, template history, and recap expose the new nested decision-split split
- report outcome deltas when both plain decision-split and history-reinforced decision-bias-snapshot-guard lanes have outcome history
## What landed
- `HyperTwistTrainingTypes.h`
- added `DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardPlainStats`
- added `DashboardAnalyticsTieBreakTemplateScopedSignalSupportBiasSnapshotGuardDecisionSplitGuardDecisionBiasSnapshotGuardStats`
- `HyperTwistTrainingRepositoryLibrary.cpp`
- added matching scoped accumulators
- `DecisionSplitGuard` runs with stored `TemplateSignalSupportDecisionBiasSnapshotDecisionKind = DecisionBiasSnapshotGuard` now flow into the history-reinforced bucket
- `DecisionSplitGuard` runs without that retained marker, including older records, flow into the plain decision-split bucket
- `HyperTwistCoachDashboardWidget.cpp`
- extended `BuildTemplateLaunchAnalyticsTieBreakTemplateSignalDecisionSplitFragment(...)`
- shared analytics detail now appends plain decision-split vs history-reinforced decision-bias-snapshot-guard lane summaries under the existing decision split
- nested split shows `snapshot-guarded-minus-plain-decision-split` success and mistake deltas when both lanes have outcome history
## Product effect
- operators can now see whether the historical decision-bias snapshot guard subset of `DecisionSplitGuard` launches is actually outperforming plain decision-split launches
- template launch history and recap inherit the same nested split automatically because they already reuse the shared analytics detail formatter
- older decision-split runs remain analyzable without migration because missing historical guard provenance is treated as plain decision-split history
## Acceptance criteria
- repo-backed template launch scoped stats retain separate `DecisionSplitGuard` buckets for plain wins and `DecisionBiasSnapshotGuard`-reinforced wins
- shared dashboard analytics detail renders the nested decision-split split anywhere template launch analytics are shown
- nested historical-guard deltas appear only when both decision-split lanes have outcome history
- older `DecisionSplitGuard` runs without retained historical-guard provenance continue to participate in analytics through the plain decision-split bucket
## Validation checklist
1. full `Development Editor|Win64` build succeeds
2. confirm scoped analytics route stored `TemplateSignalSupportDecisionBiasSnapshotDecisionKind = DecisionBiasSnapshotGuard` into the reinforced bucket
3. confirm shared analytics detail shows `plain-decision-split-guard ... | decision-bias-snapshot-guard ...`
4. confirm older `DecisionSplitGuard` runs without retained historical-guard provenance still surface under `plain-decision-split-guard`