Implement Phase 6R-A hyper puzzle catalog contract

This commit is contained in:
axiomlogicnexus 2026-05-20 22:33:19 +02:00
parent 9a75f0103e
commit 30b553b792
12 changed files with 601 additions and 23 deletions

View file

@ -114,6 +114,14 @@ FHyperTwistPuzzleDefinitionRef UHyperTwistContractLibrary::MakeSampleClassicPuzz
FHyperTwistPuzzleDefinitionRef UHyperTwistContractLibrary::MakeSampleHyperPuzzleDefinition()
{
FHyperTwistPuzzleDefinitionRef Definition;
if (UHyperTwistTrainingCatalogLibrary::TryResolveRetainedHyperPuzzleDefinition(
TEXT("hypercube/2x2x2x2"),
Definition
))
{
return Definition;
}
Definition.PuzzleId = TEXT("hypercube/2x2x2x2");
Definition.PuzzleFamily = EHyperTwistPuzzleFamily::Hypercube;
Definition.Dimension = 4;

View file

@ -7,6 +7,26 @@
namespace HyperTwistTrainingCatalogLibraryInternal
{
FHyperTwistRetainedHyperPuzzleCatalogEntry MakeRetainedHyperCatalogEntry(
const FString& PuzzleId,
const FString& DisplayName,
const TArray<int32>& SizeVector,
const FString& Variant,
const TArray<FString>& Tags,
const TArray<FString>& AliasPuzzleIds
)
{
FHyperTwistRetainedHyperPuzzleCatalogEntry Entry;
Entry.PuzzleId = PuzzleId;
Entry.DisplayName = DisplayName;
Entry.Dimension = SizeVector.Num();
Entry.SizeVector = SizeVector;
Entry.Variant = Variant;
Entry.Tags = Tags;
Entry.AliasPuzzleIds = AliasPuzzleIds;
return Entry;
}
template <typename TStruct>
bool LoadStructFromJsonFile(
const FString& JsonPath,
@ -680,6 +700,93 @@ namespace HyperTwistTrainingCatalogLibraryInternal
}
}
FHyperTwistRetainedHyperPuzzleCatalog UHyperTwistTrainingCatalogLibrary::MakeRetainedHyperPuzzleCatalog()
{
FHyperTwistRetainedHyperPuzzleCatalog Catalog;
Catalog.Entries =
{
HyperTwistTrainingCatalogLibraryInternal::MakeRetainedHyperCatalogEntry(
TEXT("hypercube/3x3x3x3"),
TEXT("3x3x3x3"),
{3, 3, 3, 3},
FString(),
{TEXT("hypercube"), TEXT("virtual"), TEXT("entry"), TEXT("retained/hyperspeedcube")},
{TEXT("3x3x3x3")}
),
HyperTwistTrainingCatalogLibraryInternal::MakeRetainedHyperCatalogEntry(
TEXT("hypercube/2x2x2x2"),
TEXT("2x2x2x2"),
{2, 2, 2, 2},
FString(),
{TEXT("hypercube"), TEXT("virtual"), TEXT("compact"), TEXT("retained/hyperspeedcube")},
{TEXT("2x2x2x2")}
),
HyperTwistTrainingCatalogLibraryInternal::MakeRetainedHyperCatalogEntry(
TEXT("hypercube/4x4x4x4"),
TEXT("4x4x4x4"),
{4, 4, 4, 4},
FString(),
{TEXT("hypercube"), TEXT("virtual"), TEXT("extended"), TEXT("retained/hyperspeedcube")},
{TEXT("4x4x4x4")}
),
HyperTwistTrainingCatalogLibraryInternal::MakeRetainedHyperCatalogEntry(
TEXT("hypercube/3x3x3x3x3"),
TEXT("3x3x3x3x3"),
{3, 3, 3, 3, 3},
FString(),
{TEXT("hypercube"), TEXT("virtual"), TEXT("higher-dimensional"), TEXT("retained/hyperspeedcube")},
{TEXT("3x3x3x3x3")}
),
HyperTwistTrainingCatalogLibraryInternal::MakeRetainedHyperCatalogEntry(
TEXT("hypercube/2x2x2x2/physical"),
TEXT("Physical 2x2x2x2"),
{2, 2, 2, 2},
TEXT("physical"),
{TEXT("hypercube"), TEXT("physical"), TEXT("retained/hyperspeedcube")},
{TEXT("phys_2x2x2x2")}
)
};
return Catalog;
}
bool UHyperTwistTrainingCatalogLibrary::TryGetRetainedHyperPuzzleCatalogEntry(
const FString& PuzzleId,
FHyperTwistRetainedHyperPuzzleCatalogEntry& OutEntry
)
{
if (PuzzleId.IsEmpty())
{
return false;
}
const FHyperTwistRetainedHyperPuzzleCatalog Catalog = MakeRetainedHyperPuzzleCatalog();
for (const FHyperTwistRetainedHyperPuzzleCatalogEntry& Entry : Catalog.Entries)
{
if (Entry.MatchesPuzzleId(PuzzleId))
{
OutEntry = Entry;
return true;
}
}
return false;
}
bool UHyperTwistTrainingCatalogLibrary::TryResolveRetainedHyperPuzzleDefinition(
const FString& PuzzleId,
FHyperTwistPuzzleDefinitionRef& OutDefinition
)
{
FHyperTwistRetainedHyperPuzzleCatalogEntry Entry;
if (!TryGetRetainedHyperPuzzleCatalogEntry(PuzzleId, Entry))
{
return false;
}
OutDefinition = Entry.ToDefinitionRef();
return true;
}
FHyperTwistContentPack UHyperTwistTrainingCatalogLibrary::MakeAlgTrainerStarterContentPack()
{
const FHyperTwistTrainingCase OLLT01 = HyperTwistTrainingCatalogLibraryInternal::MakeAlgTrainerCase(

View file

@ -20583,7 +20583,15 @@ UHyperTwistTrainingCoachLibrary::DeriveCoachGeneratedModeSelectorOptionOwnedExec
const auto IncrementPuzzleFamilyCounts = [&Surface](const FString& PuzzleId)
{
if (PuzzleId.StartsWith(TEXT("cube/")))
FHyperTwistPuzzleDefinitionRef RetainedHyperDefinition;
if (UHyperTwistTrainingCatalogLibrary::TryResolveRetainedHyperPuzzleDefinition(
PuzzleId,
RetainedHyperDefinition
))
{
++Surface.HypercubePuzzleOptionCount;
}
else if (PuzzleId.StartsWith(TEXT("cube/")))
{
++Surface.CubePuzzleOptionCount;
}

View file

@ -340,6 +340,15 @@ namespace HyperTwistTrainingLibraryInternal
FHyperTwistPuzzleDefinitionRef MakeDefinitionForCase(const FHyperTwistTrainingCase& TrainingCase)
{
FHyperTwistPuzzleDefinitionRef RetainedHyperDefinition;
if (UHyperTwistTrainingCatalogLibrary::TryResolveRetainedHyperPuzzleDefinition(
TrainingCase.PuzzleId,
RetainedHyperDefinition
))
{
return RetainedHyperDefinition;
}
FHyperTwistPuzzleDefinitionRef Definition;
Definition.PuzzleId = TrainingCase.PuzzleId;
Definition.DefinitionVersion = TEXT("2026.04");
@ -454,6 +463,15 @@ namespace HyperTwistTrainingLibraryInternal
bool MatchesPuzzleFamily(const FString& PuzzleId, EHyperTwistPuzzleFamily PuzzleFamily)
{
FHyperTwistPuzzleDefinitionRef RetainedHyperDefinition;
if (UHyperTwistTrainingCatalogLibrary::TryResolveRetainedHyperPuzzleDefinition(
PuzzleId,
RetainedHyperDefinition
))
{
return RetainedHyperDefinition.PuzzleFamily == PuzzleFamily;
}
switch (PuzzleFamily)
{
case EHyperTwistPuzzleFamily::ClassicCube:

View file

@ -1868,6 +1868,15 @@ namespace HyperTwistTrainingSubsystemInternal
EHyperTwistPuzzleFamily ResolvePuzzleFamilyFromPuzzleId(const FString& PuzzleId)
{
FHyperTwistPuzzleDefinitionRef RetainedHyperDefinition;
if (UHyperTwistTrainingCatalogLibrary::TryResolveRetainedHyperPuzzleDefinition(
PuzzleId,
RetainedHyperDefinition
))
{
return RetainedHyperDefinition.PuzzleFamily;
}
if (PuzzleId.StartsWith(TEXT("hypercube/")))
{
return EHyperTwistPuzzleFamily::Hypercube;
@ -1881,6 +1890,15 @@ namespace HyperTwistTrainingSubsystemInternal
FString ResolveNotationProfileFromPuzzleId(const FString& PuzzleId)
{
FHyperTwistPuzzleDefinitionRef RetainedHyperDefinition;
if (UHyperTwistTrainingCatalogLibrary::TryResolveRetainedHyperPuzzleDefinition(
PuzzleId,
RetainedHyperDefinition
))
{
return RetainedHyperDefinition.NotationProfile;
}
if (PuzzleId.StartsWith(TEXT("hypercube/")))
{
return TEXT("hyper-4d");

View file

@ -1,6 +1,7 @@
#pragma once
#include "CoreMinimal.h"
#include "HyperTwistCore/HyperTwistCoreTypes.h"
#include "HyperTwistTrainingCatalogImportTypes.generated.h"
USTRUCT(BlueprintType)
@ -682,3 +683,108 @@ struct FHyperTwistTrainingCatalogImportLoadReport
&& bLoadedReferenceTargets;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistRetainedHyperPuzzleCatalogEntry
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PuzzleId;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString DisplayName;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
EHyperTwistPuzzleFamily PuzzleFamily = EHyperTwistPuzzleFamily::Hypercube;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 Dimension = 4;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString DefinitionVersion = TEXT("2026.04");
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString NotationProfile = TEXT("hyper-4d");
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
TArray<int32> SizeVector;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString Variant;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
TArray<FString> Tags;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
TArray<FString> AliasPuzzleIds;
bool IsStructurallyValid() const
{
return !PuzzleId.IsEmpty()
&& !DisplayName.IsEmpty()
&& Dimension > 0
&& !DefinitionVersion.IsEmpty()
&& !NotationProfile.IsEmpty()
&& SizeVector.Num() == Dimension;
}
bool MatchesPuzzleId(const FString& CandidatePuzzleId) const
{
if (CandidatePuzzleId.Equals(PuzzleId, ESearchCase::IgnoreCase))
{
return true;
}
return AliasPuzzleIds.ContainsByPredicate([&CandidatePuzzleId](const FString& AliasPuzzleId)
{
return CandidatePuzzleId.Equals(AliasPuzzleId, ESearchCase::IgnoreCase);
});
}
FHyperTwistPuzzleDefinitionRef ToDefinitionRef() const
{
FHyperTwistPuzzleDefinitionRef Definition;
Definition.PuzzleId = PuzzleId;
Definition.PuzzleFamily = PuzzleFamily;
Definition.Dimension = Dimension;
Definition.DefinitionVersion = DefinitionVersion;
Definition.NotationProfile = NotationProfile;
Definition.SizeVector = SizeVector;
Definition.Variant = Variant;
return Definition;
}
};
USTRUCT(BlueprintType)
struct FHyperTwistRetainedHyperPuzzleCatalog
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString CatalogId = TEXT("retained/hyperspeedcube/hyper-puzzles");
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString CatalogVersion = TEXT("2026.05");
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
TArray<FHyperTwistRetainedHyperPuzzleCatalogEntry> Entries;
bool IsStructurallyValid() const
{
if (CatalogId.IsEmpty() || CatalogVersion.IsEmpty() || Entries.Num() == 0)
{
return false;
}
for (const FHyperTwistRetainedHyperPuzzleCatalogEntry& Entry : Entries)
{
if (!Entry.IsStructurallyValid())
{
return false;
}
}
return true;
}
};

View file

@ -12,6 +12,21 @@ class UNREALHYPERTWIST_API UHyperTwistTrainingCatalogLibrary : public UBlueprint
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
static FHyperTwistRetainedHyperPuzzleCatalog MakeRetainedHyperPuzzleCatalog();
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
static bool TryGetRetainedHyperPuzzleCatalogEntry(
const FString& PuzzleId,
FHyperTwistRetainedHyperPuzzleCatalogEntry& OutEntry
);
UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Catalog")
static bool TryResolveRetainedHyperPuzzleDefinition(
const FString& PuzzleId,
FHyperTwistPuzzleDefinitionRef& OutDefinition
);
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Catalog")
static FHyperTwistContentPack MakeAlgTrainerStarterContentPack();

View file

@ -0,0 +1,139 @@
// Copyright HyperTwist, Inc. All Rights Reserved.
#include "Misc/AutomationTest.h"
#include "HyperTwistBootstrap/HyperTwistContractLibrary.h"
#include "HyperTwistTraining/HyperTwistTrainingCatalogLibrary.h"
#include "HyperTwistTraining/HyperTwistTrainingLibrary.h"
#if WITH_AUTOMATION_TESTS
namespace HyperTwistHyperspeedcubePhase6RATestInternal
{
FHyperTwistTrainingDeck MakeHypercubeDeck(const FString& PuzzleId)
{
FHyperTwistTrainingDeck Deck;
Deck.DeckId = TEXT("phase6r-a/hypercube-catalog");
Deck.Title = TEXT("Phase 6R-A Hyper Puzzle Catalog");
Deck.DeliveryModes = {EHyperTwistTrainingDeliveryMode::Timer};
FHyperTwistTrainingCase TrainingCase;
TrainingCase.CaseId = TEXT("phase6r-a-case");
TrainingCase.PuzzleId = PuzzleId;
TrainingCase.PromptLabel = TEXT("Phase 6R-A Hyper Puzzle");
TrainingCase.AllowedDeliveryModes = {EHyperTwistTrainingDeliveryMode::Timer};
Deck.Cases = {TrainingCase};
return Deck;
}
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
FHyperTwistHyperspeedcubePhase6RACatalogLookupTest,
"HyperTwist.Permissive.Hyperspeedcube.Phase6R.A.CatalogLookup",
EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)
bool FHyperTwistHyperspeedcubePhase6RACatalogLookupTest::RunTest(const FString& Parameters)
{
const FHyperTwistRetainedHyperPuzzleCatalog Catalog =
UHyperTwistTrainingCatalogLibrary::MakeRetainedHyperPuzzleCatalog();
TestTrue(TEXT("The retained hyper puzzle catalog must be structurally valid."), Catalog.IsStructurallyValid());
TestTrue(TEXT("The retained hyper puzzle catalog must register multiple retained entries."), Catalog.Entries.Num() >= 5);
FHyperTwistRetainedHyperPuzzleCatalogEntry VirtualEntry;
TestTrue(
TEXT("The catalog must resolve the virtual 3x3x3x3 alias."),
UHyperTwistTrainingCatalogLibrary::TryGetRetainedHyperPuzzleCatalogEntry(TEXT("3x3x3x3"), VirtualEntry)
);
TestEqual(
TEXT("The virtual 3x3x3x3 alias must map to the canonical retained puzzle id."),
VirtualEntry.PuzzleId,
TEXT("hypercube/3x3x3x3")
);
TestEqual(
TEXT("The virtual 3x3x3x3 alias must resolve as a 4D hypercube."),
VirtualEntry.Dimension,
4
);
FHyperTwistRetainedHyperPuzzleCatalogEntry PhysicalEntry;
TestTrue(
TEXT("The catalog must resolve the physical 2x2x2x2 alias."),
UHyperTwistTrainingCatalogLibrary::TryGetRetainedHyperPuzzleCatalogEntry(TEXT("phys_2x2x2x2"), PhysicalEntry)
);
TestEqual(
TEXT("The physical 2x2x2x2 alias must map to the canonical retained puzzle id."),
PhysicalEntry.PuzzleId,
TEXT("hypercube/2x2x2x2/physical")
);
TestEqual(
TEXT("The physical 2x2x2x2 entry must preserve the physical variant label."),
PhysicalEntry.Variant,
TEXT("physical")
);
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
FHyperTwistHyperspeedcubePhase6RATrainingRunDefinitionTest,
"HyperTwist.Permissive.Hyperspeedcube.Phase6R.A.TrainingRunDefinition",
EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)
bool FHyperTwistHyperspeedcubePhase6RATrainingRunDefinitionTest::RunTest(const FString& Parameters)
{
const FHyperTwistTrainingRunState RunState = UHyperTwistTrainingLibrary::StartTrainingRun(
HyperTwistHyperspeedcubePhase6RATestInternal::MakeHypercubeDeck(TEXT("3x3x3x3")),
TEXT("phase6r-a-user"),
TEXT("phase6r-a-session"),
EHyperTwistTrainingDeliveryMode::Timer
);
TestTrue(TEXT("The bounded 6R-A deck must start a structurally valid run."), RunState.IsStructurallyValid());
TestEqual(
TEXT("The replay packet must promote the virtual 3x3x3x3 alias to the canonical retained puzzle id."),
RunState.ReplayPacket.PuzzleDefinition.PuzzleId,
TEXT("hypercube/3x3x3x3")
);
TestEqual(
TEXT("The replay packet must retain the retained hyper notation profile."),
RunState.ReplayPacket.PuzzleDefinition.NotationProfile,
TEXT("hyper-4d")
);
TestEqual(
TEXT("The replay packet must retain the 4D hypercube family."),
RunState.ReplayPacket.PuzzleDefinition.PuzzleFamily,
EHyperTwistPuzzleFamily::Hypercube
);
TestEqual(
TEXT("The replay packet must retain the 4D hypercube dimension."),
RunState.ReplayPacket.PuzzleDefinition.Dimension,
4
);
return true;
}
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
FHyperTwistHyperspeedcubePhase6RASampleDefinitionTest,
"HyperTwist.Permissive.Hyperspeedcube.Phase6R.A.SampleDefinition",
EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)
bool FHyperTwistHyperspeedcubePhase6RASampleDefinitionTest::RunTest(const FString& Parameters)
{
const FHyperTwistPuzzleDefinitionRef Definition =
UHyperTwistContractLibrary::MakeSampleHyperPuzzleDefinition();
TestEqual(
TEXT("The sample hyper definition must resolve through the retained hyper puzzle catalog."),
Definition.PuzzleId,
TEXT("hypercube/2x2x2x2")
);
TestEqual(TEXT("The sample hyper definition must remain 4D."), Definition.Dimension, 4);
TestEqual(TEXT("The sample hyper definition must retain the hyper notation profile."), Definition.NotationProfile, TEXT("hyper-4d"));
return true;
}
#endif

View file

@ -94,33 +94,39 @@ Status update on `2026-05-20`:
- the current canonical repo-row portfolio count is `75`
- all `75` current portfolio rows now have explicit root-tracker coverage
- the current implemented-row count is `24`
- the current implemented-row count is `25`
- the four later restrictive clean-room rows now implemented after the original `2026-05-13` truth
block are:
- `cubing/alg.js`
- `cubing/twisty.js`
- `HactarCE/2x2x2x2-Scrambler`
- `kash/cubedesk`
- the fifth additional implemented row is the same-day bounded permissive partial row:
- `HactarCE/Hyperspeedcube`
- the earlier first-party packet block is now confirmed landed in current code through:
- `d4f4ad3` `Add primary coach orchestration entry lane`
- `1860f14` `Add provider-backed recognition sidecar client`
- `2473665` `Overlay imported training catalog packs and finite bundles`
- the current next bounded move is the source-backed `Phase 6R-A` `HactarCE/Hyperspeedcube`
runtime-anchor widening packet, not a new restrictive packet by default
- the bounded permissive `Phase 6R-A` `HactarCE/Hyperspeedcube` puzzle-catalog contract widening
packet is now landed in current code
- `HactarCE/Hyperspeedcube` remains partially incorporated; the current next bounded move is a
source-backed `Phase 6R-B` `kkoomen/qbr` preparation/control pass, not a new restrictive packet
by default
- use the repo-row README census, the portfolio standing refresh backfill, and the `2R-A`
ownership contract for the current queue after that correction
This file now also preserves the current truth that future models must not lose:
- current curated HyperTwist shallow-eval set: `75` repos
- currently verified live/implemented in checked `UnrealHyperTwist` surfaces: `24`
- permissive live lanes: `13`
- currently verified live/implemented in checked `UnrealHyperTwist` surfaces: `25`
- permissive live lanes: `14`
- boundary-sensitive live lanes: `6`
- restrictive live lanes: `5`
The thirteen permissive live lanes are:
The fourteen permissive live lanes are:
- `Aarav2709/KubeTimr`
- `HactarCE/Hyperspeedcube`
- `apache/echarts`
- `abunickabhi/5style-Trainer`
- `google/model-viewer`
@ -203,8 +209,7 @@ Current practical interpretation:
- the landed `PostHog/posthog` boundary-sensitive widening packet now lives in `docs/HYPERTWIST_PHASE_4R_PACKET_4R_D_POSTHOG_CONTROL_PLANE_IMPLEMENTATION_2026-05-13.md`
- the landed `screenpipe/screenpipe` boundary-sensitive widening packet now lives in `docs/HYPERTWIST_PHASE_4R_PACKET_4R_E_SCREENPIPE_CAPTURE_HISTORY_IMPLEMENTATION_2026-05-13.md`
- the landed `remotion-dev/remotion` boundary-sensitive widening packet now lives in `docs/HYPERTWIST_PHASE_4R_PACKET_4R_F_REMOTION_MEDIA_EXPORT_IMPLEMENTATION_2026-05-13.md`
- the next bounded move is the bounded `Phase 6R-A` `HactarCE/Hyperspeedcube` runtime-anchor
widening packet
- the next bounded move is a source-backed `Phase 6R-B` `kkoomen/qbr` preparation/control pass
Companion docs:
@ -219,6 +224,7 @@ Companion docs:
- `docs/HYPERTWIST_PHASE_3R_PACKET_3R_A_KUBETIMR_IMPLEMENTATION_2026-05-13.md`
- `docs/HYPERTWIST_PHASE_3R_PACKET_3R_B_HYPERCUBING_XYZ_IMPLEMENTATION_2026-05-13.md`
- `docs/HYPERTWIST_PHASE_3R_PACKET_3R_F_BROWSER_SPATIAL_SUPPORT_IMPLEMENTATION_2026-05-13.md`
- `docs/arch/HYPERTWIST_PHASE6R_A_HYPERSPEEDCUBE_PUZZLE_CATALOG_IMPLEMENTATION_PACKET_2026-05-20.md`
- `docs/HYPERTWIST_REPO_STATE_BOARD_2026-05-11.md`
## Landed live-lane legal records
@ -1196,6 +1202,10 @@ Current licensing judgment:
- not a clean-room case
- treat as a bounded permissive donor candidate whose technical widening is still constrained by the
retained `Phase 6R-A` ownership contract
- the first narrower bounded implementation slice is now landed in current code:
- hyper puzzle catalog contract
- the row remains only partially incorporated; DSL, notation, replay verification, and stats-shape
widening remain deferred
Source basis:
@ -1231,6 +1241,9 @@ Approved working posture:
permission to transplant the whole Rust application shell
- do not let this row absorb non-Euclidean topology ownership that remains queued for
`roice3/MagicTile`
- after the landed puzzle-catalog slice, the next queue head should move to a source-backed
`Phase 6R-B` `kkoomen/qbr` preparation/control pass rather than pretending the entire
`Hyperspeedcube` family is already closed
### `coqui-ai/TTS`

View file

@ -0,0 +1,130 @@
# HyperTwist Phase 6R-A Hyperspeedcube puzzle catalog implementation packet
Created on `2026-05-20`
## Status
- first-party HyperTwist packet
- bounded permissive `Phase 6R-A` implementation slice
## Purpose
This packet lands the first narrower bounded slice from the retained `HactarCE/Hyperspeedcube`
runtime-anchor row.
The landed slice is:
- first-party hyper puzzle catalog contract
It is not:
- a full `Hyperspeedcube` row transplant
- a puzzle-definition DSL packet
- a notation parser or serializer packet
- a replay verification packet
- a stats-shape packet
- a `qbr`, `rubix-cube-solver`, or `MagicTile` packet
## Current authority basis
This implementation packet stands on:
- `docs/HYPERTWIST_PHASE_0R_PACKET_0R_A_EVALUATION_2026-05-12.md`
- `docs/HYPERTWIST_PHASE_2R_PACKET_2R_A_OWNERSHIP_AND_ACCEPTANCE_CONTRACT_2026-05-13.md`
- `docs/REPO_LICENSE_TRACKING.md`
- `docs/arch/HYPERTWIST_PHASE6R_A_HYPERSPEEDCUBE_RUNTIME_ANCHOR_PREPARATION_PACKET_2026-05-20.md`
The retained owner remains:
- `HactarCE/Hyperspeedcube`
The granted family remains bounded to:
- puzzle catalog contract
- puzzle-definition DSL boundary
- notation grammar and serialization boundary
- replay-event taxonomy and verification boundary
- stats-shape and solve-record contract
This packet lands only the first family in that granted set.
## Landed scope
The current code now owns a retained hyper puzzle catalog contract through:
- retained catalog contract types for canonical hyper puzzle entries and the catalog wrapper
- `UHyperTwistTrainingCatalogLibrary` catalog construction and lookup helpers
- canonical hyper-definition resolution for:
- `3x3x3x3`
- `2x2x2x2`
- `4x4x4x4`
- `3x3x3x3x3`
- `phys_2x2x2x2`
- replay-packet definition shaping in `UHyperTwistTrainingLibrary`
- session/runtime family and notation resolution in `UHyperTwistTrainingSubsystem`
- coach option family counting in `UHyperTwistTrainingCoachLibrary`
- sample hyper definition routing in `UHyperTwistContractLibrary`
## Why this is still intentionally bounded
This packet replaces sample / heuristic hyper puzzle identity with a catalog-owned contract, but it
does not widen into the neighboring retained families.
Still deferred:
- puzzle-definition DSL parsing and authoring
- notation parsing and serialization
- replay-event taxonomy widening and replay verification
- stats-shape / solve-record widening
- broad view / simulation UX
- non-Euclidean topology ownership
- `qbr` calibration / perception ownership
- `rubix-cube-solver` correction / explanation ownership
## Validation
Build validation:
- `Build.bat UnrealHyperTwistEditor Win64 Development -Project='C:\HyperTwist\UnrealHyperTwist\UnrealHyperTwist.uproject' -WaitMutex -NoHotReloadFromIDE`
Focused automation validation:
- `Automation RunTests HyperTwist.Permissive.Hyperspeedcube.Phase6R.A`
Regression automation validation:
- `Automation RunTests HyperTwist.CleanRoom.CubeDesk`
- `Automation RunTests HyperTwist.CleanRoom.HactarCE`
Expected covered tests:
- `CatalogLookup`
- `SampleDefinition`
- `TrainingRunDefinition`
- existing `CubeDesk` clean-room regression suite
- existing `HactarCE` clean-room regression suite
## Queue effect
This packet consumes the current `Phase 6R-A` implementation slice.
`HactarCE/Hyperspeedcube` remains only partially incorporated:
- landed now:
- puzzle catalog contract
- still deferred:
- DSL
- notation
- replay verification
- stats-shape
The next clean move is not another immediate `Hyperspeedcube` widening by default.
The next queue head should be:
- a source-backed `Phase 6R-B` `kkoomen/qbr` preparation/control pass
Keep the legal sequencing guard visible there:
- do not copy or redistribute `src/assets/arial-unicode-ms.ttf` without separate confirmation or
replacement

View file

@ -4,8 +4,10 @@ Created on `2026-05-20`
## Status
- first-party HyperTwist packet
- historical same-day preparation authority
- bounded post-Phase-`5R` preparation slice
- the first bounded implementation slice now lands separately under:
- `docs/arch/HYPERTWIST_PHASE6R_A_HYPERSPEEDCUBE_PUZZLE_CATALOG_IMPLEMENTATION_PACKET_2026-05-20.md`
## Purpose
@ -183,7 +185,7 @@ Before widening starts, that packet should:
## Suggested next packet
The next explicit implementation-facing packet after this preparation slice should be:
The next explicit implementation-facing packet after this preparation slice is now:
- a bounded permissive `Phase 6R-A` `HactarCE/Hyperspeedcube` puzzle-catalog contract widening
packet

View file

@ -3,20 +3,26 @@
Status update on `2026-05-20`:
- the canonical HyperTwist repo-row portfolio is now treated as `75` rows, not `71`
- currently implemented rows are now `24`, not `20`
- the additional current implemented rows are the later-landed restrictive clean-room lanes:
- currently implemented rows are now `25`, not `20`
- four of the additional current implemented rows are the later-landed restrictive clean-room lanes:
- `cubing/alg.js`
- `cubing/twisty.js`
- `HactarCE/2x2x2x2-Scrambler`
- `kash/cubedesk`
- the fifth additional current implemented row is the same-day bounded permissive partial row:
- `HactarCE/Hyperspeedcube`
- the current next bounded move is **not** another restrictive packet by default
- the earlier first-party packet block that was still being treated as next is now confirmed landed:
- `d4f4ad3` `Add primary coach orchestration entry lane`
- `1860f14` `Add provider-backed recognition sidecar client`
- `2473665` `Overlay imported training catalog packs and finite bundles`
- the generic source-backed `Phase 6R-A` `HactarCE/Hyperspeedcube` control pass is now consumed
- the current next bounded move is the bounded permissive `Phase 6R-A`
`HactarCE/Hyperspeedcube` puzzle-catalog contract widening packet
- the bounded permissive `Phase 6R-A` `HactarCE/Hyperspeedcube` puzzle-catalog contract widening
packet is now landed in current code
- `HactarCE/Hyperspeedcube` remains partially incorporated; DSL, notation, replay verification,
and stats-shape families stay deferred
- the current next bounded move is a source-backed `Phase 6R-B` `kkoomen/qbr` preparation/control
pass
- the repo-row implementation queue is now live from that `Phase 6R-A` entry point rather than
waiting on another first-party packet
@ -44,8 +50,8 @@ Donor-strength rule:
- route difficulty changes how retained value may enter the product, not whether it may win technically
- current shallow-eval set: `75` repos
- currently verified live/implemented in checked Unreal surfaces: `24`
- permissive live lanes: `13`
- currently verified live/implemented in checked Unreal surfaces: `25`
- permissive live lanes: `14`
- boundary-sensitive live lanes: `6`
- restrictive live lanes: `5`
- the restrictive landed lanes are:
@ -55,7 +61,7 @@ Donor-strength rule:
- `HactarCE/2x2x2x2-Scrambler`
- `kash/cubedesk`
- each restrictive landed lane is to be treated as properly clean-roomed and implemented afterward
- `Phase 0R` is now closed for the remaining `51` non-live rows
- `Phase 0R` is now closed for the remaining `50` non-live rows
- `Phase 1R` is now closed as the retained-set contract and handoff overhaul
- `Phase 2R` is now closed as the retained-set ownership and acceptance packet sequence
- `Phase 3R-A` is now closed as the landed `Aarav2709/KubeTimr` timer subsystem widening packet
@ -75,11 +81,10 @@ Current routing truth:
- retained rows total: `68`
- discarded from the active retained set: `3`
- active non-live implementation-board rows: `39`
- active non-live implementation-board rows: `38`
- retained benchmark, oracle, or clean-room-later rows outside the active implementation board: `9`
The next bounded move is the bounded `Phase 6R-A` `HactarCE/Hyperspeedcube` puzzle-catalog
contract widening packet.
The next bounded move is a source-backed `Phase 6R-B` `kkoomen/qbr` preparation/control pass.
Queue interpretation after that packet:
@ -87,14 +92,23 @@ Queue interpretation after that packet:
- highest current repo-row queue pressure sits in:
- `kkoomen/qbr`
- `vivaansinghvi07/rubix-cube-solver`
- the bounded speech-input / voice sidecar set
- keep the adjacent legal sequencing guards visible when those rows come up:
- `roice3/MagicTile`
- `HactarCE/Hyperspeedcube` remains a partially landed row rather than a closed row:
- landed:
- puzzle catalog contract
- still deferred:
- DSL
- notation / serialization
- replay verification
- stats-shape
- after the `Phase 6R-B` control pass, keep the adjacent legal sequencing guards visible:
- `kkoomen/qbr`
- do not copy or redistribute `src/assets/arial-unicode-ms.ttf` without separate confirmation
or replacement
- `vivaansinghvi07/rubix-cube-solver`
- do not copy or redistribute `frontend/lib/twistysim.min.js` without preserving or replacing
its upstream provenance/license
- the bounded speech-input / voice sidecar set
- keep the optional `Phase 3R-G` browser comparison lane deferred unless the landed primary browser
spatial stack exposes a real gap