# HyperTwist Phase 4 gameplay primary coach CTA surface packet

Created on `2026-05-07`

Status:

- first-party HyperTwist packet
- bounded Phase `4` gameplay-facing consumer slice

## Purpose

This packet closes the next thin gameplay-facing consumer seam above the panel-widget and session-actor coach execution helpers by exposing one pure primary coach CTA descriptor / availability surface that follows the exact same branch order as the runtime primary launch path.

The open tasks were:

- stop forcing gameplay / Blueprint callers to reconstruct queue-vs-follow-up-vs-recommended launch readiness from raw `CachedCoachPanelState` booleans just to render one truthful coach CTA
- expose the actual primary coach action kind, label, availability, and source label through a narrow pure surface instead of through dashboard-specific branching
- keep that descriptor aligned with the existing `StartDisplayedPrimaryCoachAction()` / `StartPrimaryCoachTrainingRun()` execution path

It is not:

- a new backend continuity packet
- a broader gameplay UI composition pass
- a dashboard rewrite
- a queue-policy or analytics-policy change

## Scope

Bounded lane:

- add a first-party primary coach CTA surface type in shared training types
- add coach-library helpers that resolve the primary coach action kind and derive a narrow CTA surface from `FHyperTwistTrainingCoachPanelState`
- expose that derived surface on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`
- keep the descriptor aligned with the exact runtime branch order used by `StartPrimaryCoachAction()`

Out of scope:

- changing coach action selection policy
- changing queue execution behavior
- adding richer composed gameplay HUD widgets
- widening into defer/promote secondary controls in the same packet

## Why this was the right next packet

Before this slice:

- gameplay-facing panel/session consumers already had displayed-action execution helpers
- those surfaces already resolved default coach provenance for execution
- callers could launch the current coach action without dashboard code

But one thin consumer seam was still open:

- callers still had to inspect `bCanStartQueuedRun`, `bCanStartCoachFollowUpRun`, `bHasFollowUpGuidance`, and `bCanStartCoachRecommendedRun` themselves to decide what the single primary CTA actually meant
- that would have duplicated the same branch order that the runtime already uses in `StartPrimaryCoachAction()`

That meant:

- execution was thin
- but truthful rendering of the primary CTA still required caller-side reconstruction

So the next bounded move was:

- keep the execution path unchanged
- and expose one narrow pure descriptor derived from the same branch order

## What landed

Primary code changes:

- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingTypes.h`
  - added `FHyperTwistTrainingCoachPrimaryActionSurface`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingCoachLibrary.h`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingCoachLibrary.cpp`
  - added `ResolvePrimaryCoachActionKind(...)`
  - added `DerivePrimaryCoachActionSurface(...)`
  - the branch order now matches `StartPrimaryCoachAction()` exactly: queue first, then follow-up-with-guidance, then recommended
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingPanelWidget.h`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingPanelWidget.cpp`
  - added `GetDisplayedPrimaryCoachActionSurface()`
  - the returned surface is enriched with the same resolved start-action source label used by the execution helper
- `UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistTraining/HyperTwistTrainingSessionActor.h`
- `UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingSessionActor.cpp`
  - added `GetDisplayedPrimaryCoachActionSurface()`
  - the returned surface is enriched with the same resolved start-action source label used by the actor execution helper

## Product effect

The first gameplay-facing coach consumer layer is now more complete:

- gameplay / Blueprint callers can bind one primary coach CTA from a pure descriptor instead of replaying runtime branch logic
- the descriptor and the execution verb now point at the same queue / follow-up / recommended action ordering
- callers can render truthful CTA availability and provenance without reaching into dashboard code

## Acceptance criteria

- shared training types expose a narrow primary coach CTA surface
- coach-library derivation matches `StartPrimaryCoachAction()` branch order exactly
- panel-widget callers can fetch the displayed primary coach CTA surface directly
- session-actor callers can fetch the displayed primary coach CTA surface directly
- full product build succeeds

## Validation checklist

1. build `UnrealHyperTwist.sln` / `UnrealHyperTwistEditor`
2. confirm the new primary CTA surface compiles in shared types and coach library
3. confirm panel-widget getters compile and return the derived surface
4. confirm session-actor getters compile and return the derived surface

## Validation result

- full `Development Editor|Win64` build succeeded on `2026-05-07`
- build completed with the same preexisting `UnrealMCP` / `PythonScriptPlugin` dependency warning and `0` errors

## Next bounded follow-on slice

- stay on the same gameplay-facing consumer lane and add the matching thin secondary queue-control descriptor / availability surface for defer and promote actions on `HyperTwistTrainingPanelWidget` and `HyperTwistTrainingSessionActor`, so callers can bind the common non-primary queue controls without reading raw queue-state booleans
