From 496279eade6cd8d17f9d227169c735b075fe3240 Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Thu, 28 May 2026 04:46:27 +0200 Subject: [PATCH] Implement Phase 6R-M1 memory contracts and ledger --- .../HyperTwistContractLibrary.cpp | 365 +++-- .../HyperTwistMemoryCoreLibrary.cpp | 1318 +++++++++++++++++ .../HyperTwistContractLibrary.h | 10 + .../HyperTwistMemoryCoreLibrary.h | 21 + .../HyperTwistMemory/HyperTwistMemoryTypes.h | 329 ++++ ...TwistMemoryPhase6RM1LedgerContractTest.cpp | 190 +++ ...LEDGER_IMPLEMENTATION_PACKET_2026-05-28.md | 142 ++ ...ND_LEDGER_PREPARATION_PACKET_2026-05-28.md | 118 ++ ...PERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md | 3 + ...HASE_IMPLEMENTATION_DOCTRINE_2026-05-21.md | 9 + .../HyperTwist/ARCHITECTURE.md | 2 + .../HyperTwist/FEATURE_REGISTRY.md | 1 + .../HyperTwist/PROVENANCE_AND_TRUST_MODEL.md | 2 + .../HyperTwist/ROADMAP.md | 6 + 14 files changed, 2420 insertions(+), 96 deletions(-) create mode 100644 UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistMemory/HyperTwistMemoryCoreLibrary.cpp create mode 100644 UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistMemory/HyperTwistMemoryCoreLibrary.h create mode 100644 UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistMemory/HyperTwistMemoryTypes.h create mode 100644 UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistMemoryPhase6RM1LedgerContractTest.cpp create mode 100644 docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_IMPLEMENTATION_PACKET_2026-05-28.md create mode 100644 docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_PREPARATION_PACKET_2026-05-28.md diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp index 775c13a..4fd06cc 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp @@ -1,5 +1,6 @@ #include "HyperTwistBootstrap/HyperTwistContractLibrary.h" +#include "HyperTwistMemory/HyperTwistMemoryCoreLibrary.h" #include "HyperTwistRecognition/HyperTwistRecognitionReplayLibrary.h" #include "HyperTwistReplay/HyperTwistReplayReviewLibrary.h" #include "HyperTwistTraining/HyperTwistTrainingCatalogLibrary.h" @@ -24,6 +25,187 @@ namespace HyperTwistContractLibraryInternal return FJsonObjectConverter::JsonObjectStringToUStruct(Json, &OutValue, 0, 0); } + FHyperTwistCoachSessionQueueSummary MakeSampleCoachSessionQueueSummaryManual() + { + FHyperTwistCoachSessionQueueSummary QueueSummary; + const FHyperTwistTrainingRunStepResult StepResult = + UHyperTwistContractLibrary::MakeSampleTrainingRunStepResult(); + if (!StepResult.IsStructurallyValid()) + { + return QueueSummary; + } + + QueueSummary.UserId = StepResult.UpdatedRunState.Session.UserId; + QueueSummary.ReferenceUtc = TEXT("2026-04-28T12:12:00Z"); + QueueSummary.FocusDeckId = StepResult.UpdatedRunState.Session.DeckId; + QueueSummary.FocusMethodSegmentId = TEXT("cfop-cross"); + QueueSummary.PrimaryQueueLabel = TEXT("primary-brief"); + QueueSummary.NextQueueLabel = TEXT("follow-up-brief"); + QueueSummary.bHasImmediateQueue = true; + QueueSummary.bNeedsArchiveAwareSequencing = true; + + FHyperTwistCoachSessionQueueEntry PrimaryEntry; + PrimaryEntry.EntryId = TEXT("coach_queue_primary"); + PrimaryEntry.SourceLabel = TEXT("primary-brief"); + PrimaryEntry.Priority = EHyperTwistCoachPriority::Elevated; + PrimaryEntry.PriorityScore = 78.0f; + PrimaryEntry.Headline = TEXT("Primary coach review block"); + PrimaryEntry.SuggestedMode = EHyperTwistTrainingDeliveryMode::CoachReviewed; + PrimaryEntry.SuggestedSelectionPolicy = EHyperTwistTrainingSelectionPolicy::Weighted; + PrimaryEntry.FocusDeckId = QueueSummary.FocusDeckId; + PrimaryEntry.FocusMethodSegmentId = QueueSummary.FocusMethodSegmentId; + PrimaryEntry.FocusCaseIds = { TEXT("cross_case_1"), TEXT("cross_case_2") }; + QueueSummary.Entries.Add(PrimaryEntry); + + FHyperTwistCoachSessionQueueEntry FollowUpEntry; + FollowUpEntry.EntryId = TEXT("coach_queue_follow_up"); + FollowUpEntry.SourceLabel = TEXT("follow-up-brief"); + FollowUpEntry.Priority = EHyperTwistCoachPriority::Advisory; + FollowUpEntry.PriorityScore = 61.0f; + FollowUpEntry.Headline = TEXT("Follow-up coaching block"); + FollowUpEntry.SuggestedMode = EHyperTwistTrainingDeliveryMode::VirtualCube; + FollowUpEntry.SuggestedSelectionPolicy = EHyperTwistTrainingSelectionPolicy::Scripted; + FollowUpEntry.FocusDeckId = QueueSummary.FocusDeckId; + FollowUpEntry.FocusMethodSegmentId = QueueSummary.FocusMethodSegmentId; + FollowUpEntry.FocusCaseIds = { TEXT("cross_case_2"), TEXT("cross_case_3") }; + FollowUpEntry.bRequiresFollowUp = true; + QueueSummary.Entries.Add(FollowUpEntry); + + FHyperTwistCoachSessionQueueEntry ArchiveEntry; + ArchiveEntry.EntryId = TEXT("coach_queue_archive"); + ArchiveEntry.SourceLabel = TEXT("archive-policy"); + ArchiveEntry.Priority = EHyperTwistCoachPriority::Advisory; + ArchiveEntry.PriorityScore = 56.0f; + ArchiveEntry.Headline = TEXT("Archive retention review block"); + ArchiveEntry.SuggestedMode = EHyperTwistTrainingDeliveryMode::Timer; + ArchiveEntry.SuggestedSelectionPolicy = EHyperTwistTrainingSelectionPolicy::Weighted; + ArchiveEntry.FocusDeckId = QueueSummary.FocusDeckId; + ArchiveEntry.FocusMethodSegmentId = QueueSummary.FocusMethodSegmentId; + ArchiveEntry.FocusCaseIds = { TEXT("cross_case_4") }; + ArchiveEntry.bRequiresArchiveRetentionTuning = true; + QueueSummary.Entries.Add(ArchiveEntry); + + return QueueSummary; + } + + FHyperTwistTrainingCoachSessionQueueState MakeSampleCoachSessionQueueStateManual() + { + FHyperTwistTrainingCoachSessionQueueState QueueState = + UHyperTwistTrainingRepositoryLibrary::BuildCoachSessionQueueState( + MakeSampleCoachSessionQueueSummaryManual(), + TEXT("coach_queue_active"), + TEXT("2026-04-28T12:12:00Z") + ); + + QueueState = UHyperTwistTrainingRepositoryLibrary::DeferCoachSessionQueueEntry( + QueueState, + TEXT("coach_queue_follow_up"), + TEXT("2026-04-28T18:00:00Z"), + TEXT("follow-up-held-behind-primary"), + false, + TEXT("2026-04-28T12:13:00Z") + ); + QueueState = UHyperTwistTrainingRepositoryLibrary::DeferCoachSessionQueueEntry( + QueueState, + TEXT("coach_queue_archive"), + TEXT("2026-04-29T09:00:00Z"), + TEXT("archive-retention-window"), + true, + TEXT("2026-04-28T12:14:00Z") + ); + + return QueueState; + } + + FHyperTwistTrainingRepositoryState AppendSampleCoachArtifacts( + const FHyperTwistTrainingRepositoryState& RepositoryState + ) + { + FHyperTwistTrainingRepositoryState UpdatedState = RepositoryState; + + const FHyperTwistTrainingCoachActionPlan CoachActionPlan = + UHyperTwistContractLibrary::MakeSampleTrainingCoachActionPlan(); + if (CoachActionPlan.IsStructurallyValid()) + { + UpdatedState = UHyperTwistTrainingRepositoryLibrary::UpsertCoachActionPlan( + UpdatedState, + CoachActionPlan + ); + } + + const FHyperTwistTrainingCoachSessionQueueState CoachSessionQueueState = + MakeSampleCoachSessionQueueStateManual(); + if (CoachSessionQueueState.IsStructurallyValid()) + { + UpdatedState = UHyperTwistTrainingRepositoryLibrary::UpsertCoachSessionQueueState( + UpdatedState, + CoachSessionQueueState + ); + } + + return UpdatedState; + } + + FHyperTwistTrainingRepositoryState BuildSampleTrainingRepositoryStateBase() + { + const FHyperTwistTrainingRunStepResult StepResult = + UHyperTwistContractLibrary::MakeSampleTrainingRunStepResult(); + if (!StepResult.IsStructurallyValid()) + { + return FHyperTwistTrainingRepositoryState(); + } + + FHyperTwistTrainingRepositoryState RepositoryState; + RepositoryState = UHyperTwistTrainingRepositoryLibrary::RecordRunState( + RepositoryState, + StepResult.UpdatedRunState + ); + + const TArray DerivedTemplates = + UHyperTwistTrainingRepositoryLibrary::DeriveTrainingSessionTemplates( + RepositoryState, + StepResult.UpdatedRunState.Session.UserId, + TEXT("2026-04-28T12:05:00Z") + ); + if (DerivedTemplates.Num() > 0) + { + FHyperTwistTrainingSessionTemplate CustomizedTemplate = DerivedTemplates[0]; + CustomizedTemplate.Title = TEXT("Pinned Recovery Review"); + CustomizedTemplate.GuidanceLabel = TEXT("user-customized-recovery"); + CustomizedTemplate.RecommendedCaseCount = FMath::Max(2, CustomizedTemplate.RecommendedCaseCount); + CustomizedTemplate.SuggestedMode = EHyperTwistTrainingDeliveryMode::VirtualCube; + CustomizedTemplate.SourceTemplateId = CustomizedTemplate.TemplateId; + CustomizedTemplate.bUserCustomized = true; + CustomizedTemplate.LastUpdatedAtUtc = TEXT("2026-04-28T12:10:00Z"); + RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertStoredTrainingSessionTemplate( + RepositoryState, + CustomizedTemplate + ); + } + + const FHyperTwistTrainingMethodDrillFavoriteEntry FavoriteEntry = + UHyperTwistContractLibrary::MakeSampleMethodDrillFavoriteEntry(); + if (FavoriteEntry.IsStructurallyValid()) + { + RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertMethodDrillFavorite( + RepositoryState, + FavoriteEntry + ); + } + + const FHyperTwistTrainingMethodDrillBatch DrillBatch = + UHyperTwistContractLibrary::MakeSampleMethodDrillBatch(); + if (DrillBatch.IsStructurallyValid()) + { + RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertMethodDrillBatch( + RepositoryState, + DrillBatch + ); + } + + return RepositoryState; + } + void AppendLe16(TArray& Buffer, const uint16 Value) { Buffer.Add(static_cast(Value & 0xff)); @@ -3489,77 +3671,67 @@ FHyperTwistTrainingTimingBreakdown UHyperTwistContractLibrary::MakeSampleTrainin FHyperTwistTrainingRepositoryState UHyperTwistContractLibrary::MakeSampleTrainingRepositoryState() { - const FHyperTwistTrainingRunStepResult StepResult = MakeSampleTrainingRunStepResult(); - if (!StepResult.IsStructurallyValid()) - { - return FHyperTwistTrainingRepositoryState(); - } + FHyperTwistTrainingRepositoryState RepositoryState = + HyperTwistContractLibraryInternal::BuildSampleTrainingRepositoryStateBase(); - FHyperTwistTrainingRepositoryState RepositoryState; - RepositoryState = UHyperTwistTrainingRepositoryLibrary::RecordRunState(RepositoryState, StepResult.UpdatedRunState); - - const TArray DerivedTemplates = - UHyperTwistTrainingRepositoryLibrary::DeriveTrainingSessionTemplates( - RepositoryState, - StepResult.UpdatedRunState.Session.UserId, - TEXT("2026-04-28T12:05:00Z") - ); - if (DerivedTemplates.Num() > 0) + const FHyperTwistTrainingReviewPlanState ReviewPlanState = MakeSampleTrainingReviewPlanState(); + if (ReviewPlanState.IsStructurallyValid()) { - FHyperTwistTrainingSessionTemplate CustomizedTemplate = DerivedTemplates[0]; - CustomizedTemplate.Title = TEXT("Pinned Recovery Review"); - CustomizedTemplate.GuidanceLabel = TEXT("user-customized-recovery"); - CustomizedTemplate.RecommendedCaseCount = FMath::Max(2, CustomizedTemplate.RecommendedCaseCount); - CustomizedTemplate.SuggestedMode = EHyperTwistTrainingDeliveryMode::VirtualCube; - CustomizedTemplate.SourceTemplateId = CustomizedTemplate.TemplateId; - CustomizedTemplate.bUserCustomized = true; - CustomizedTemplate.LastUpdatedAtUtc = TEXT("2026-04-28T12:10:00Z"); - RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertStoredTrainingSessionTemplate( + RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertReviewPlan( RepositoryState, - CustomizedTemplate - ); - } - - const FHyperTwistTrainingMethodDrillFavoriteEntry FavoriteEntry = MakeSampleMethodDrillFavoriteEntry(); - if (FavoriteEntry.IsStructurallyValid()) - { - RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertMethodDrillFavorite( - RepositoryState, - FavoriteEntry - ); - } - - const FHyperTwistTrainingMethodDrillBatch DrillBatch = MakeSampleMethodDrillBatch(); - if (DrillBatch.IsStructurallyValid()) - { - RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertMethodDrillBatch( - RepositoryState, - DrillBatch - ); - } - - const FHyperTwistTrainingCoachActionPlan CoachActionPlan = MakeSampleTrainingCoachActionPlan(); - if (CoachActionPlan.IsStructurallyValid()) - { - RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertCoachActionPlan( - RepositoryState, - CoachActionPlan - ); - } - - const FHyperTwistTrainingCoachSessionQueueState CoachSessionQueueState = - MakeSampleTrainingCoachSessionQueueState(); - if (CoachSessionQueueState.IsStructurallyValid()) - { - RepositoryState = UHyperTwistTrainingRepositoryLibrary::UpsertCoachSessionQueueState( - RepositoryState, - CoachSessionQueueState + ReviewPlanState ); } return RepositoryState; } +FHyperTwistMemoryLedgerState UHyperTwistContractLibrary::MakeSampleTrainingMemoryLedgerState() +{ + FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + RepositoryState = HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts(RepositoryState); + + FString UserId; + if (RepositoryState.RunRecords.Num() > 0 && !RepositoryState.RunRecords[0].Session.UserId.IsEmpty()) + { + UserId = RepositoryState.RunRecords[0].Session.UserId; + } + else if (RepositoryState.LearnerStates.Num() > 0 && !RepositoryState.LearnerStates[0].UserId.IsEmpty()) + { + UserId = RepositoryState.LearnerStates[0].UserId; + } + else if (RepositoryState.ReviewPlans.Num() > 0 && !RepositoryState.ReviewPlans[0].UserId.IsEmpty()) + { + UserId = RepositoryState.ReviewPlans[0].UserId; + } + else if (RepositoryState.StoredSessionTemplates.Num() > 0 && + !RepositoryState.StoredSessionTemplates[0].UserId.IsEmpty()) + { + UserId = RepositoryState.StoredSessionTemplates[0].UserId; + } + else if (RepositoryState.StoredCoachActionPlans.Num() > 0 && + !RepositoryState.StoredCoachActionPlans[0].UserId.IsEmpty()) + { + UserId = RepositoryState.StoredCoachActionPlans[0].UserId; + } + else if (RepositoryState.StoredCoachSessionQueues.Num() > 0 && + !RepositoryState.StoredCoachSessionQueues[0].UserId.IsEmpty()) + { + UserId = RepositoryState.StoredCoachSessionQueues[0].UserId; + } + + if (UserId.IsEmpty()) + { + return FHyperTwistMemoryLedgerState(); + } + + return UHyperTwistMemoryCoreLibrary::DeriveMemoryLedgerState( + RepositoryState, + UserId, + TEXT("2026-04-28T12:40:00Z") + ); +} + FHyperTwistTrainingRepositoryIntegrityReport UHyperTwistContractLibrary::MakeSampleTrainingRepositoryIntegrityReport() { FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); @@ -4089,7 +4261,8 @@ TArray UHyperTwistContractLibrary::MakeSa return TArray(); } - const FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + const FHyperTwistTrainingRepositoryState RepositoryState = + HyperTwistContractLibraryInternal::BuildSampleTrainingRepositoryStateBase(); return UHyperTwistTrainingRepositoryLibrary::ListCaseRecommendationsForDeck( RepositoryState, StepResult.UpdatedRunState.ActiveDeck, @@ -4225,8 +4398,10 @@ FHyperTwistTrainingCoachActionPlanSummary UHyperTwistContractLibrary::MakeSample return FHyperTwistTrainingCoachActionPlanSummary(); } + FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + RepositoryState = HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts(RepositoryState); return UHyperTwistTrainingRepositoryLibrary::DeriveCoachActionPlanSummary( - MakeSampleTrainingRepositoryState(), + RepositoryState, StepResult.UpdatedRunState.Session.UserId, TEXT("2026-04-28T12:05:00Z") ); @@ -4234,8 +4409,12 @@ FHyperTwistTrainingCoachActionPlanSummary UHyperTwistContractLibrary::MakeSample FHyperTwistTrainingCoachActionPlanOutcomeSummary UHyperTwistContractLibrary::MakeSampleTrainingCoachActionPlanOutcomeSummary() { + const FHyperTwistTrainingRepositoryState RepositoryState = + HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts( + MakeSampleTrainingRepositoryState() + ); return UHyperTwistTrainingRepositoryLibrary::DeriveCoachActionPlanOutcomeSummary( - MakeSampleTrainingRepositoryState(), + RepositoryState, MakeSampleTrainingCoachActionPlan(), TEXT("2026-04-28T12:12:00Z") ); @@ -4244,6 +4423,7 @@ FHyperTwistTrainingCoachActionPlanOutcomeSummary UHyperTwistContractLibrary::Mak FHyperTwistTrainingCoachActionSequenceSummary UHyperTwistContractLibrary::MakeSampleTrainingCoachActionSequenceSummary() { FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + RepositoryState = HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts(RepositoryState); const FHyperTwistTrainingCoachActionPlan RootPlan = MakeSampleTrainingCoachActionPlan(); const FHyperTwistCoachBrief FollowUpBrief = MakeSampleTrainingCoachFollowUpBrief(); const FHyperTwistTrainingCoachActionPlan FollowUpPlan = @@ -4280,6 +4460,7 @@ FHyperTwistTrainingCoachActionSequenceSummary UHyperTwistContractLibrary::MakeSa FHyperTwistTrainingCoachActionClosureSummary UHyperTwistContractLibrary::MakeSampleTrainingCoachActionClosureSummary() { FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + RepositoryState = HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts(RepositoryState); const FHyperTwistTrainingCoachActionPlan RootPlan = MakeSampleTrainingCoachActionPlan(); const FHyperTwistCoachBrief FollowUpBrief = MakeSampleTrainingCoachFollowUpBrief(); const FHyperTwistTrainingCoachActionPlan FollowUpPlan = @@ -4321,8 +4502,10 @@ FHyperTwistTrainingCoachClosureMemorySummary UHyperTwistContractLibrary::MakeSam return FHyperTwistTrainingCoachClosureMemorySummary(); } + FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + RepositoryState = HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts(RepositoryState); return UHyperTwistTrainingRepositoryLibrary::DeriveCoachClosureMemorySummary( - MakeSampleTrainingRepositoryState(), + RepositoryState, StepResult.UpdatedRunState.Session.UserId, TEXT("2026-04-28T12:20:00Z") ); @@ -4337,6 +4520,7 @@ FHyperTwistTrainingCoachRecommendationHistorySummary UHyperTwistContractLibrary: } FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + RepositoryState = HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts(RepositoryState); const FHyperTwistCoachBrief FollowUpBrief = MakeSampleTrainingCoachFollowUpBrief(); const FHyperTwistTrainingCoachActionPlan FollowUpPlan = UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan( @@ -4373,6 +4557,7 @@ FHyperTwistTrainingCoachCarryForwardPolicySummary UHyperTwistContractLibrary::Ma } FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + RepositoryState = HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts(RepositoryState); const FHyperTwistCoachBrief FollowUpBrief = MakeSampleTrainingCoachFollowUpBrief(); const FHyperTwistTrainingCoachActionPlan FollowUpPlan = UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan( @@ -4409,6 +4594,7 @@ FHyperTwistTrainingCoachArchivePolicySummary UHyperTwistContractLibrary::MakeSam } FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); + RepositoryState = HyperTwistContractLibraryInternal::AppendSampleCoachArtifacts(RepositoryState); const FHyperTwistCoachBrief FollowUpBrief = MakeSampleTrainingCoachFollowUpBrief(); const FHyperTwistTrainingCoachActionPlan FollowUpPlan = UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan( @@ -4447,40 +4633,12 @@ FHyperTwistCoachBrief UHyperTwistContractLibrary::MakeSampleTrainingCoachFollowU FHyperTwistCoachSessionQueueSummary UHyperTwistContractLibrary::MakeSampleTrainingCoachSessionQueueSummary() { - return UHyperTwistTrainingCoachLibrary::DeriveCoachSessionQueueSummary( - MakeSampleTrainingCoachBrief(), - MakeSampleTrainingCoachFollowUpBrief(), - MakeSampleTrainingCoachMemorySnapshot(), - MakeSampleTrainingCoachArchivePolicySummary(), - MakeSampleTrainingReviewProgramSummary() - ); + return HyperTwistContractLibraryInternal::MakeSampleCoachSessionQueueSummaryManual(); } FHyperTwistTrainingCoachSessionQueueState UHyperTwistContractLibrary::MakeSampleTrainingCoachSessionQueueState() { - FHyperTwistTrainingCoachSessionQueueState QueueState = UHyperTwistTrainingRepositoryLibrary::BuildCoachSessionQueueState( - MakeSampleTrainingCoachSessionQueueSummary(), - TEXT("coach_queue_active"), - TEXT("2026-04-28T12:12:00Z") - ); - - QueueState = UHyperTwistTrainingRepositoryLibrary::DeferCoachSessionQueueEntry( - QueueState, - TEXT("coach_queue_follow_up"), - TEXT("2026-04-28T18:00:00Z"), - TEXT("follow-up-held-behind-primary"), - false, - TEXT("2026-04-28T12:13:00Z") - ); - QueueState = UHyperTwistTrainingRepositoryLibrary::DeferCoachSessionQueueEntry( - QueueState, - TEXT("coach_queue_archive"), - TEXT("2026-04-29T09:00:00Z"), - TEXT("archive-retention-window"), - true, - TEXT("2026-04-28T12:14:00Z") - ); - return QueueState; + return HyperTwistContractLibraryInternal::MakeSampleCoachSessionQueueStateManual(); } FHyperTwistCoachScheduleHorizonSummary UHyperTwistContractLibrary::MakeSampleTrainingCoachScheduleHorizonSummary() @@ -4633,6 +4791,13 @@ FString UHyperTwistContractLibrary::SerializeTrainingRepositoryStateToJson(const return HyperTwistContractLibraryInternal::SerializeStructToJson(RepositoryState); } +FString UHyperTwistContractLibrary::SerializeMemoryLedgerStateToJson( + const FHyperTwistMemoryLedgerState& MemoryLedgerState +) +{ + return HyperTwistContractLibraryInternal::SerializeStructToJson(MemoryLedgerState); +} + FString UHyperTwistContractLibrary::SerializeTrainingTimerExportPacketToJson( const FHyperTwistTrainingTimerExportPacket& TimerExportPacket ) @@ -4692,6 +4857,14 @@ bool UHyperTwistContractLibrary::DeserializeTrainingRepositoryStateFromJson(cons return HyperTwistContractLibraryInternal::DeserializeStructFromJson(Json, OutRepositoryState); } +bool UHyperTwistContractLibrary::DeserializeMemoryLedgerStateFromJson( + const FString& Json, + FHyperTwistMemoryLedgerState& OutMemoryLedgerState +) +{ + return HyperTwistContractLibraryInternal::DeserializeStructFromJson(Json, OutMemoryLedgerState); +} + bool UHyperTwistContractLibrary::DeserializeTrainingTimerExportPacketFromJson( const FString& Json, FHyperTwistTrainingTimerExportPacket& OutTimerExportPacket diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistMemory/HyperTwistMemoryCoreLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistMemory/HyperTwistMemoryCoreLibrary.cpp new file mode 100644 index 0000000..2e16c09 --- /dev/null +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistMemory/HyperTwistMemoryCoreLibrary.cpp @@ -0,0 +1,1318 @@ +#include "HyperTwistMemory/HyperTwistMemoryCoreLibrary.h" + +#include "HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.h" + +namespace HyperTwistMemoryCoreLibraryInternal +{ + FString ResolveReferenceUtc(const FString& ReferenceUtc) + { + return ReferenceUtc.IsEmpty() ? FDateTime::UtcNow().ToIso8601() : ReferenceUtc; + } + + FString MakeDeckCaseKey(const FString& DeckId, const FString& CaseId) + { + return DeckId + TEXT("|") + CaseId; + } + + FHyperTwistMemoryProvenanceLink MakeProvenanceLink( + const FHyperTwistMemoryEntityDescriptor& ParentEntity, + const FString& SourceLabel + ) + { + FHyperTwistMemoryProvenanceLink ProvenanceLink; + ProvenanceLink.ParentEntityId = ParentEntity.EntityId; + ProvenanceLink.ParentLane = ParentEntity.Lane; + ProvenanceLink.ParentRecordKind = ParentEntity.RecordKind; + ProvenanceLink.ParentReferenceUtc = ParentEntity.ReferenceUtc; + ProvenanceLink.ParentSourceLabel = + SourceLabel.IsEmpty() ? ParentEntity.RecordKind : SourceLabel; + ProvenanceLink.bParentAuthoritative = + ParentEntity.AuthorityKind == EHyperTwistMemoryAuthorityKind::Authoritative; + return ProvenanceLink; + } + + void TryAppendEntityProvenance( + const TMap& EntitiesById, + const FString& EntityId, + const FString& SourceLabel, + TArray& OutProvenanceLinks + ) + { + const FHyperTwistMemoryEntityDescriptor* ParentEntity = EntitiesById.Find(EntityId); + if (ParentEntity == nullptr) + { + return; + } + + const bool bAlreadyLinked = OutProvenanceLinks.ContainsByPredicate( + [&EntityId](const FHyperTwistMemoryProvenanceLink& ExistingLink) + { + return ExistingLink.ParentEntityId == EntityId; + } + ); + if (bAlreadyLinked) + { + return; + } + + OutProvenanceLinks.Add(MakeProvenanceLink(*ParentEntity, SourceLabel)); + } + + FHyperTwistMemoryLaneContract MakeLaneContract( + const EHyperTwistMemoryLane Lane, + const TCHAR* LaneId, + const TCHAR* DisplayLabel, + const EHyperTwistMemoryAuthorityKind AuthorityKind, + const TCHAR* DefaultSettingsKey, + const TCHAR* DefaultFeatureGateId, + const bool bCurrentEvidencePresent, + const TCHAR* Summary + ) + { + FHyperTwistMemoryLaneContract LaneContract; + LaneContract.Lane = Lane; + LaneContract.LaneId = LaneId; + LaneContract.DisplayLabel = DisplayLabel; + LaneContract.AuthorityKind = AuthorityKind; + LaneContract.DefaultSettingsKey = DefaultSettingsKey; + LaneContract.DefaultFeatureGateId = DefaultFeatureGateId; + LaneContract.bFirstPartyOwned = true; + LaneContract.bCurrentEvidencePresent = bCurrentEvidencePresent; + LaneContract.Summary = Summary; + return LaneContract; + } + + FHyperTwistMemoryFeatureGate MakeFeatureGate( + const TCHAR* GateId, + const TCHAR* SettingsKey, + const TCHAR* DisplayLabel, + const EHyperTwistMemoryLane Lane, + const EHyperTwistMemoryFeatureGateDefaultState DefaultState, + const bool bUserControllable, + const bool bDisableAllowed, + const TCHAR* Summary + ) + { + FHyperTwistMemoryFeatureGate FeatureGate; + FeatureGate.GateId = GateId; + FeatureGate.SettingsKey = SettingsKey; + FeatureGate.DisplayLabel = DisplayLabel; + FeatureGate.Lane = Lane; + FeatureGate.DefaultState = DefaultState; + FeatureGate.bUserControllable = bUserControllable; + FeatureGate.bDisableAllowed = bDisableAllowed; + FeatureGate.Summary = Summary; + return FeatureGate; + } + + FHyperTwistMemorySettingsProfile MakeSettingsProfile( + const TCHAR* ProfileId, + const TCHAR* DisplayLabel, + const EHyperTwistMemoryContextAssemblyProfile ContextAssemblyProfile, + const TArray& EnabledFeatureGateIds, + const TArray& DisabledFeatureGateIds, + const TCHAR* Summary + ) + { + FHyperTwistMemorySettingsProfile SettingsProfile; + SettingsProfile.ProfileId = ProfileId; + SettingsProfile.DisplayLabel = DisplayLabel; + SettingsProfile.ContextAssemblyProfile = ContextAssemblyProfile; + SettingsProfile.EnabledFeatureGateIds = EnabledFeatureGateIds; + SettingsProfile.DisabledFeatureGateIds = DisabledFeatureGateIds; + SettingsProfile.Summary = Summary; + return SettingsProfile; + } + + void AddEntity( + FHyperTwistMemoryLedgerState& LedgerState, + TMap& EntitiesById, + const FHyperTwistMemoryEntityDescriptor& Entity + ) + { + if (!Entity.IsStructurallyValid() || EntitiesById.Contains(Entity.EntityId)) + { + return; + } + + LedgerState.Entities.Add(Entity); + EntitiesById.Add(Entity.EntityId, Entity); + + switch (Entity.AuthorityKind) + { + case EHyperTwistMemoryAuthorityKind::Authoritative: + ++LedgerState.AuthoritativeEntityCount; + break; + case EHyperTwistMemoryAuthorityKind::SemiAuthoritative: + ++LedgerState.SemiAuthoritativeEntityCount; + break; + case EHyperTwistMemoryAuthorityKind::DerivedOnly: + ++LedgerState.DerivedEntityCount; + break; + default: + break; + } + } +} + +FHyperTwistMemoryLedgerState UHyperTwistMemoryCoreLibrary::DeriveMemoryLedgerState( + const FHyperTwistTrainingRepositoryState& RepositoryState, + const FString& UserId, + const FString& ReferenceUtc +) +{ + FHyperTwistMemoryLedgerState LedgerState; + if (UserId.IsEmpty()) + { + return LedgerState; + } + + const FString ResolvedReferenceUtc = + HyperTwistMemoryCoreLibraryInternal::ResolveReferenceUtc(ReferenceUtc); + LedgerState.UserId = UserId; + LedgerState.ReferenceUtc = ResolvedReferenceUtc; + + LedgerState.LaneContracts = { + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::IdentityPolicy, + TEXT("memory-lane/identity-policy"), + TEXT("Preferences"), + EHyperTwistMemoryAuthorityKind::Authoritative, + TEXT("memory.identity_policy.enabled"), + TEXT("memory-gate/identity-policy"), + true, + TEXT("First-party trust, consent, and retention policy surfaces.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::WorkspaceRecall, + TEXT("memory-lane/workspace-recall"), + TEXT("Workspace Recall"), + EHyperTwistMemoryAuthorityKind::Authoritative, + TEXT("memory.workspace_recall.enabled"), + TEXT("memory-gate/workspace-recall"), + true, + TEXT("First-party cockpit state, focus anchors, and recent context.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::ChronicleCapture, + TEXT("memory-lane/chronicle-capture"), + TEXT("Training Chronicle"), + EHyperTwistMemoryAuthorityKind::Authoritative, + TEXT("memory.chronicle_capture.enabled"), + TEXT("memory-gate/chronicle-capture"), + true, + TEXT("Append-only training and runtime event evidence.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::ContinuityResume, + TEXT("memory-lane/continuity-resume"), + TEXT("Session Continuity"), + EHyperTwistMemoryAuthorityKind::Authoritative, + TEXT("memory.continuity_resume.enabled"), + TEXT("memory-gate/continuity-resume"), + true, + TEXT("First-party session continuity and resume pointers.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::SharedCoordination, + TEXT("memory-lane/shared-coordination"), + TEXT("Shared Context"), + EHyperTwistMemoryAuthorityKind::SemiAuthoritative, + TEXT("memory.shared_coordination.enabled"), + TEXT("memory-gate/shared-coordination"), + true, + TEXT("Scoped shared context across coach, replay, and sidecar flows.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::RecallRetrieval, + TEXT("memory-lane/recall-retrieval"), + TEXT("Smart Recall"), + EHyperTwistMemoryAuthorityKind::SemiAuthoritative, + TEXT("memory.recall_retrieval.enabled"), + TEXT("memory-gate/recall-retrieval"), + true, + TEXT("Rebuildable retrieval and history-search indexes.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::CognitiveConsolidated, + TEXT("memory-lane/cognitive-consolidated"), + TEXT("Coach Memory"), + EHyperTwistMemoryAuthorityKind::SemiAuthoritative, + TEXT("memory.cognitive_consolidated.enabled"), + TEXT("memory-gate/cognitive-consolidated"), + true, + TEXT("Provenance-backed long-term training state and coach follow-up signals.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::KnowledgeWiki, + TEXT("memory-lane/knowledge-wiki"), + TEXT("Training Atlas"), + EHyperTwistMemoryAuthorityKind::Authoritative, + TEXT("memory.knowledge_wiki.enabled"), + TEXT("memory-gate/knowledge-wiki"), + true, + TEXT("Browsable and reviewable curriculum and knowledge objects.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::UserNotes, + TEXT("memory-lane/user-notes"), + TEXT("Training Notes"), + EHyperTwistMemoryAuthorityKind::Authoritative, + TEXT("memory.user_notes.enabled"), + TEXT("memory-gate/user-notes"), + false, + TEXT("User-authored note content remains separate and explicitly owned.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::ProvenanceLedger, + TEXT("memory-lane/provenance-ledger"), + TEXT("Memory Ledger"), + EHyperTwistMemoryAuthorityKind::Authoritative, + TEXT("memory.provenance_ledger.enabled"), + TEXT("memory-gate/provenance-ledger"), + true, + TEXT("Lineage and trust ledger for every non-raw memory surface.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::DerivedCompacted, + TEXT("memory-lane/derived-compacted"), + TEXT("Compact Views"), + EHyperTwistMemoryAuthorityKind::DerivedOnly, + TEXT("memory.derived_compacted.enabled"), + TEXT("memory-gate/derived-compacted"), + true, + TEXT("Discardable compact summaries and reduced context packets.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeLaneContract( + EHyperTwistMemoryLane::ProceduralWorkflow, + TEXT("memory-lane/procedural-workflow"), + TEXT("Workflow Memory"), + EHyperTwistMemoryAuthorityKind::Authoritative, + TEXT("memory.procedural_workflow.enabled"), + TEXT("memory-gate/procedural-workflow"), + true, + TEXT("Durable templates, drill workflows, queues, and follow-up routines.") + ) + }; + + LedgerState.FeatureGates = { + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/identity-policy"), + TEXT("memory.identity_policy.enabled"), + TEXT("Identity Policy"), + EHyperTwistMemoryLane::IdentityPolicy, + EHyperTwistMemoryFeatureGateDefaultState::RequiredEnabled, + false, + false, + TEXT("Keep consent, retention, and provider policy first-party owned.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/workspace-recall"), + TEXT("memory.workspace_recall.enabled"), + TEXT("Workspace Recall"), + EHyperTwistMemoryLane::WorkspaceRecall, + EHyperTwistMemoryFeatureGateDefaultState::RequiredEnabled, + false, + false, + TEXT("Preserve cockpit state and focus anchors as first-party authority.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/chronicle-capture"), + TEXT("memory.chronicle_capture.enabled"), + TEXT("Chronicle Capture"), + EHyperTwistMemoryLane::ChronicleCapture, + EHyperTwistMemoryFeatureGateDefaultState::RequiredEnabled, + false, + false, + TEXT("Keep append-only chronicle evidence active for later provenance.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/continuity-resume"), + TEXT("memory.continuity_resume.enabled"), + TEXT("Continuity Resume"), + EHyperTwistMemoryLane::ContinuityResume, + EHyperTwistMemoryFeatureGateDefaultState::RequiredEnabled, + false, + false, + TEXT("Keep resume pointers and active continuity fragments available.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/shared-coordination"), + TEXT("memory.shared_coordination.enabled"), + TEXT("Shared Coordination"), + EHyperTwistMemoryLane::SharedCoordination, + EHyperTwistMemoryFeatureGateDefaultState::EnabledByDefault, + true, + true, + TEXT("Allow revocable shared context without promoting it to durable cognition.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/recall-retrieval"), + TEXT("memory.recall_retrieval.enabled"), + TEXT("Recall Retrieval"), + EHyperTwistMemoryLane::RecallRetrieval, + EHyperTwistMemoryFeatureGateDefaultState::EnabledByDefault, + true, + true, + TEXT("Permit rebuildable history search and retrieval indexes.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/cognitive-consolidated"), + TEXT("memory.cognitive_consolidated.enabled"), + TEXT("Cognitive Consolidated"), + EHyperTwistMemoryLane::CognitiveConsolidated, + EHyperTwistMemoryFeatureGateDefaultState::EnabledByDefault, + true, + true, + TEXT("Expose provenance-backed coach-memory and follow-up consolidation.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/knowledge-wiki"), + TEXT("memory.knowledge_wiki.enabled"), + TEXT("Knowledge Wiki"), + EHyperTwistMemoryLane::KnowledgeWiki, + EHyperTwistMemoryFeatureGateDefaultState::EnabledByDefault, + true, + true, + TEXT("Keep curated knowledge available without promoting raw chronicle data.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/user-notes"), + TEXT("memory.user_notes.enabled"), + TEXT("User Notes"), + EHyperTwistMemoryLane::UserNotes, + EHyperTwistMemoryFeatureGateDefaultState::DisabledByDefault, + true, + true, + TEXT("Do not auto-enable note capture until explicit user ownership is active.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/provenance-ledger"), + TEXT("memory.provenance_ledger.enabled"), + TEXT("Provenance Ledger"), + EHyperTwistMemoryLane::ProvenanceLedger, + EHyperTwistMemoryFeatureGateDefaultState::RequiredEnabled, + false, + false, + TEXT("Require lineage preservation for every non-raw memory surface.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/derived-compacted"), + TEXT("memory.derived_compacted.enabled"), + TEXT("Derived Compacted"), + EHyperTwistMemoryLane::DerivedCompacted, + EHyperTwistMemoryFeatureGateDefaultState::EnabledByDefault, + true, + true, + TEXT("Allow discardable compact views and reduced context packets.") + ), + HyperTwistMemoryCoreLibraryInternal::MakeFeatureGate( + TEXT("memory-gate/procedural-workflow"), + TEXT("memory.procedural_workflow.enabled"), + TEXT("Procedural Workflow"), + EHyperTwistMemoryLane::ProceduralWorkflow, + EHyperTwistMemoryFeatureGateDefaultState::RequiredEnabled, + false, + false, + TEXT("Keep templates, queues, and follow-up workflows first-party owned.") + ) + }; + + LedgerState.EconomicRetentionProfile = + HyperTwistMemoryCoreLibraryInternal::MakeSettingsProfile( + TEXT("memory-profile/economic-retention"), + TEXT("Economic-Retention Mode"), + EHyperTwistMemoryContextAssemblyProfile::EconomicRetentionMode, + { + TEXT("memory-gate/identity-policy"), + TEXT("memory-gate/workspace-recall"), + TEXT("memory-gate/chronicle-capture"), + TEXT("memory-gate/continuity-resume"), + TEXT("memory-gate/knowledge-wiki"), + TEXT("memory-gate/provenance-ledger"), + TEXT("memory-gate/procedural-workflow") + }, + { + TEXT("memory-gate/shared-coordination"), + TEXT("memory-gate/recall-retrieval"), + TEXT("memory-gate/cognitive-consolidated"), + TEXT("memory-gate/user-notes"), + TEXT("memory-gate/derived-compacted") + }, + TEXT("Minimum active memory posture while preserving first-party contracts and provenance.") + ); + LedgerState.MaxRetentionProfile = + HyperTwistMemoryCoreLibraryInternal::MakeSettingsProfile( + TEXT("memory-profile/max-retention"), + TEXT("Max-Retention Mode"), + EHyperTwistMemoryContextAssemblyProfile::MaxRetentionMode, + { + TEXT("memory-gate/identity-policy"), + TEXT("memory-gate/workspace-recall"), + TEXT("memory-gate/chronicle-capture"), + TEXT("memory-gate/continuity-resume"), + TEXT("memory-gate/shared-coordination"), + TEXT("memory-gate/recall-retrieval"), + TEXT("memory-gate/cognitive-consolidated"), + TEXT("memory-gate/knowledge-wiki"), + TEXT("memory-gate/provenance-ledger"), + TEXT("memory-gate/derived-compacted"), + TEXT("memory-gate/procedural-workflow") + }, + { + TEXT("memory-gate/user-notes") + }, + TEXT("High-retention posture for broader context assembly before uncertainty becomes dangerous.") + ); + + TMap EntitiesById; + TMap RunRecordEntityIdByDeckCaseKey; + TMap LearnerStateEntityIdByDeckCaseKey; + TMap ReviewPlanEntityIdByPlanId; + TMap CoachPlanEntityIdByPlanId; + TMap QueueEntityIdByQueueId; + FString PolicyEntityId; + FString LedgerContractEntityId; + FString FirstRunRecordEntityId; + FString FirstLearnerStateEntityId; + FString FirstReviewPlanEntityId; + FString FirstCoachPlanEntityId; + FString FirstQueueEntityId; + FString ReviewProgramEntityId; + FString CoachMemorySnapshotEntityId; + FString LearnerProfileEntityId; + + { + FHyperTwistMemoryEntityDescriptor PolicyEntity; + PolicyEntity.EntityId = FString::Printf( + TEXT("memory-entity/policy/current/%s"), + *UserId + ); + PolicyEntity.RecordKind = TEXT("memory-policy-profile"); + PolicyEntity.DisplayLabel = TEXT("Memory Policy Profile"); + PolicyEntity.UserId = UserId; + PolicyEntity.ReferenceUtc = ResolvedReferenceUtc; + PolicyEntity.Lane = EHyperTwistMemoryLane::IdentityPolicy; + PolicyEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity(LedgerState, EntitiesById, PolicyEntity); + PolicyEntityId = PolicyEntity.EntityId; + } + + { + FHyperTwistMemoryEntityDescriptor LedgerContractEntity; + LedgerContractEntity.EntityId = FString::Printf( + TEXT("memory-entity/provenance/ledger/current/%s"), + *UserId + ); + LedgerContractEntity.RecordKind = TEXT("memory-ledger-contract"); + LedgerContractEntity.DisplayLabel = TEXT("Memory Ledger Contract"); + LedgerContractEntity.UserId = UserId; + LedgerContractEntity.ReferenceUtc = ResolvedReferenceUtc; + LedgerContractEntity.Lane = EHyperTwistMemoryLane::ProvenanceLedger; + LedgerContractEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity(LedgerState, EntitiesById, LedgerContractEntity); + LedgerContractEntityId = LedgerContractEntity.EntityId; + } + + for (const FHyperTwistTrainingRunRecord& RunRecord : RepositoryState.RunRecords) + { + if (RunRecord.Session.UserId != UserId || !RunRecord.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor RunEntity; + RunEntity.EntityId = FString::Printf( + TEXT("memory-entity/chronicle/run-record/%s"), + *RunRecord.Session.TrainingSessionId + ); + RunEntity.RecordKind = TEXT("training-run-record"); + RunEntity.DisplayLabel = TEXT("Training Run Record"); + RunEntity.UserId = UserId; + RunEntity.DeckId = RunRecord.Session.DeckId; + RunEntity.ReferenceUtc = + RunRecord.LastUpdatedAtUtc.IsEmpty() ? ResolvedReferenceUtc : RunRecord.LastUpdatedAtUtc; + RunEntity.Lane = EHyperTwistMemoryLane::ChronicleCapture; + RunEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity(LedgerState, EntitiesById, RunEntity); + + if (FirstRunRecordEntityId.IsEmpty()) + { + FirstRunRecordEntityId = RunEntity.EntityId; + } + + for (const FHyperTwistTrainingAttempt& Attempt : RunRecord.Attempts) + { + if (Attempt.CaseId.IsEmpty()) + { + continue; + } + + const FString CaseKey = HyperTwistMemoryCoreLibraryInternal::MakeDeckCaseKey( + RunRecord.Session.DeckId, + Attempt.CaseId + ); + RunRecordEntityIdByDeckCaseKey.FindOrAdd(CaseKey) = RunEntity.EntityId; + } + } + + for (const FHyperTwistTrainingReviewPlanState& ReviewPlan : RepositoryState.ReviewPlans) + { + if (ReviewPlan.UserId != UserId || !ReviewPlan.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor ReviewPlanEntity; + ReviewPlanEntity.EntityId = FString::Printf( + TEXT("memory-entity/workflow/review-plan/%s"), + *ReviewPlan.PlanId + ); + ReviewPlanEntity.RecordKind = TEXT("training-review-plan"); + ReviewPlanEntity.DisplayLabel = TEXT("Training Review Plan"); + ReviewPlanEntity.UserId = UserId; + ReviewPlanEntity.DeckId = ReviewPlan.SourceDeckId; + ReviewPlanEntity.ReferenceUtc = + ReviewPlan.ReferenceUtc.IsEmpty() ? ResolvedReferenceUtc : ReviewPlan.ReferenceUtc; + ReviewPlanEntity.Lane = EHyperTwistMemoryLane::ProceduralWorkflow; + ReviewPlanEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + ReviewPlanEntity + ); + + ReviewPlanEntityIdByPlanId.Add(ReviewPlan.PlanId, ReviewPlanEntity.EntityId); + if (FirstReviewPlanEntityId.IsEmpty()) + { + FirstReviewPlanEntityId = ReviewPlanEntity.EntityId; + } + } + + for (const FHyperTwistTrainingSessionTemplate& SessionTemplate : RepositoryState.StoredSessionTemplates) + { + if (SessionTemplate.UserId != UserId || !SessionTemplate.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor SessionTemplateEntity; + SessionTemplateEntity.EntityId = FString::Printf( + TEXT("memory-entity/workflow/session-template/%s"), + *SessionTemplate.TemplateId + ); + SessionTemplateEntity.RecordKind = TEXT("training-session-template"); + SessionTemplateEntity.DisplayLabel = TEXT("Training Session Template"); + SessionTemplateEntity.UserId = UserId; + SessionTemplateEntity.DeckId = SessionTemplate.FocusDeckId; + SessionTemplateEntity.ReferenceUtc = + SessionTemplate.LastUpdatedAtUtc.IsEmpty() + ? ResolvedReferenceUtc + : SessionTemplate.LastUpdatedAtUtc; + SessionTemplateEntity.Lane = EHyperTwistMemoryLane::ProceduralWorkflow; + SessionTemplateEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + SessionTemplateEntity + ); + } + + for (const FHyperTwistTrainingMethodDrillFavoriteEntry& FavoriteEntry : + RepositoryState.StoredMethodDrillFavorites) + { + if (FavoriteEntry.UserId != UserId || !FavoriteEntry.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor FavoriteEntity; + FavoriteEntity.EntityId = FString::Printf( + TEXT("memory-entity/workflow/method-drill-favorite/%s/%s"), + *FavoriteEntry.DrillId, + *FavoriteEntry.CaseId + ); + FavoriteEntity.RecordKind = TEXT("method-drill-favorite"); + FavoriteEntity.DisplayLabel = TEXT("Method Drill Favorite"); + FavoriteEntity.UserId = UserId; + FavoriteEntity.DeckId = FavoriteEntry.SourceDeckId; + FavoriteEntity.ReferenceUtc = + FavoriteEntry.AddedAtUtc.IsEmpty() ? ResolvedReferenceUtc : FavoriteEntry.AddedAtUtc; + FavoriteEntity.Lane = EHyperTwistMemoryLane::ProceduralWorkflow; + FavoriteEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity(LedgerState, EntitiesById, FavoriteEntity); + } + + for (const FHyperTwistTrainingMethodDrillBatch& DrillBatch : + RepositoryState.StoredMethodDrillBatches) + { + if (DrillBatch.UserId != UserId || !DrillBatch.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor DrillBatchEntity; + DrillBatchEntity.EntityId = FString::Printf( + TEXT("memory-entity/workflow/method-drill-batch/%s"), + *DrillBatch.BatchId + ); + DrillBatchEntity.RecordKind = TEXT("method-drill-batch"); + DrillBatchEntity.DisplayLabel = TEXT("Method Drill Batch"); + DrillBatchEntity.UserId = UserId; + DrillBatchEntity.DeckId = DrillBatch.SourceDeckId; + DrillBatchEntity.ReferenceUtc = + DrillBatch.LastUpdatedAtUtc.IsEmpty() ? ResolvedReferenceUtc : DrillBatch.LastUpdatedAtUtc; + DrillBatchEntity.Lane = EHyperTwistMemoryLane::ProceduralWorkflow; + DrillBatchEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity(LedgerState, EntitiesById, DrillBatchEntity); + } + + for (const FHyperTwistTrainingCoachActionPlan& CoachActionPlan : + RepositoryState.StoredCoachActionPlans) + { + if (CoachActionPlan.UserId != UserId || !CoachActionPlan.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor CoachPlanEntity; + CoachPlanEntity.EntityId = FString::Printf( + TEXT("memory-entity/workflow/coach-action-plan/%s"), + *CoachActionPlan.PlanId + ); + CoachPlanEntity.RecordKind = TEXT("coach-action-plan"); + CoachPlanEntity.DisplayLabel = TEXT("Coach Action Plan"); + CoachPlanEntity.UserId = UserId; + CoachPlanEntity.DeckId = CoachActionPlan.FocusDeckId; + CoachPlanEntity.ReferenceUtc = + CoachActionPlan.ReferenceUtc.IsEmpty() ? ResolvedReferenceUtc : CoachActionPlan.ReferenceUtc; + CoachPlanEntity.Lane = EHyperTwistMemoryLane::ProceduralWorkflow; + CoachPlanEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity(LedgerState, EntitiesById, CoachPlanEntity); + + CoachPlanEntityIdByPlanId.Add(CoachActionPlan.PlanId, CoachPlanEntity.EntityId); + if (FirstCoachPlanEntityId.IsEmpty()) + { + FirstCoachPlanEntityId = CoachPlanEntity.EntityId; + } + } + + for (const FHyperTwistTrainingCoachSessionQueueState& QueueState : + RepositoryState.StoredCoachSessionQueues) + { + if (QueueState.UserId != UserId || !QueueState.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor QueueEntity; + QueueEntity.EntityId = FString::Printf( + TEXT("memory-entity/workflow/coach-session-queue/%s"), + *QueueState.QueueId + ); + QueueEntity.RecordKind = TEXT("coach-session-queue"); + QueueEntity.DisplayLabel = TEXT("Coach Session Queue"); + QueueEntity.UserId = UserId; + QueueEntity.DeckId = QueueState.FocusDeckId; + QueueEntity.ReferenceUtc = + QueueState.LastUpdatedAtUtc.IsEmpty() ? ResolvedReferenceUtc : QueueState.LastUpdatedAtUtc; + QueueEntity.Lane = EHyperTwistMemoryLane::ProceduralWorkflow; + QueueEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::Authoritative; + HyperTwistMemoryCoreLibraryInternal::AddEntity(LedgerState, EntitiesById, QueueEntity); + + QueueEntityIdByQueueId.Add(QueueState.QueueId, QueueEntity.EntityId); + if (FirstQueueEntityId.IsEmpty()) + { + FirstQueueEntityId = QueueEntity.EntityId; + } + } + + for (const FHyperTwistTrainingCaseLearnerState& LearnerState : RepositoryState.LearnerStates) + { + if (LearnerState.UserId != UserId || !LearnerState.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor LearnerStateEntity; + LearnerStateEntity.EntityId = FString::Printf( + TEXT("memory-entity/cognitive/case-learner-state/%s/%s"), + *LearnerState.DeckId, + *LearnerState.CaseId + ); + LearnerStateEntity.RecordKind = TEXT("case-learner-state"); + LearnerStateEntity.DisplayLabel = TEXT("Case Learner State"); + LearnerStateEntity.UserId = UserId; + LearnerStateEntity.DeckId = LearnerState.DeckId; + LearnerStateEntity.ReferenceUtc = + LearnerState.LastReviewedAtUtc.IsEmpty() + ? (LearnerState.DueAtUtc.IsEmpty() ? ResolvedReferenceUtc : LearnerState.DueAtUtc) + : LearnerState.LastReviewedAtUtc; + LearnerStateEntity.Lane = EHyperTwistMemoryLane::CognitiveConsolidated; + LearnerStateEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::SemiAuthoritative; + LearnerStateEntity.bDerived = true; + + const FString CaseKey = HyperTwistMemoryCoreLibraryInternal::MakeDeckCaseKey( + LearnerState.DeckId, + LearnerState.CaseId + ); + if (const FString* RunEntityId = RunRecordEntityIdByDeckCaseKey.Find(CaseKey)) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + *RunEntityId, + TEXT("chronicle-run-record"), + LearnerStateEntity.ProvenanceLinks + ); + } + if (LearnerStateEntity.ProvenanceLinks.Num() == 0 && !FirstRunRecordEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstRunRecordEntityId, + TEXT("chronicle-run-record"), + LearnerStateEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + LearnerStateEntity + ); + LearnerStateEntityIdByDeckCaseKey.Add(CaseKey, LearnerStateEntity.EntityId); + if (FirstLearnerStateEntityId.IsEmpty()) + { + FirstLearnerStateEntityId = LearnerStateEntity.EntityId; + } + } + + const FHyperTwistTrainingReviewProgramSummary ReviewProgramSummary = + UHyperTwistTrainingRepositoryLibrary::DeriveReviewProgramSummary( + RepositoryState, + UserId, + ResolvedReferenceUtc + ); + if (ReviewProgramSummary.IsStructurallyValid()) + { + FHyperTwistMemoryEntityDescriptor ReviewProgramEntity; + ReviewProgramEntity.EntityId = FString::Printf( + TEXT("memory-entity/recall/review-program-summary/%s"), + *UserId + ); + ReviewProgramEntity.RecordKind = TEXT("review-program-summary"); + ReviewProgramEntity.DisplayLabel = TEXT("Review Program Summary"); + ReviewProgramEntity.UserId = UserId; + ReviewProgramEntity.DeckId = ReviewProgramSummary.FocusDeckId; + ReviewProgramEntity.ReferenceUtc = ReviewProgramSummary.ReferenceUtc; + ReviewProgramEntity.Lane = EHyperTwistMemoryLane::RecallRetrieval; + ReviewProgramEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::SemiAuthoritative; + ReviewProgramEntity.bDerived = true; + if (const FString* ReviewPlanEntityId = + ReviewPlanEntityIdByPlanId.Find(ReviewProgramSummary.CurrentPlanId)) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + *ReviewPlanEntityId, + TEXT("review-plan"), + ReviewProgramEntity.ProvenanceLinks + ); + } + if (ReviewProgramEntity.ProvenanceLinks.Num() == 0) + { + if (const FString* ReviewPlanEntityId = + ReviewPlanEntityIdByPlanId.Find(ReviewProgramSummary.LastCompletedPlanId)) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + *ReviewPlanEntityId, + TEXT("review-plan"), + ReviewProgramEntity.ProvenanceLinks + ); + } + } + if (ReviewProgramEntity.ProvenanceLinks.Num() == 0 && !FirstReviewPlanEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstReviewPlanEntityId, + TEXT("review-plan"), + ReviewProgramEntity.ProvenanceLinks + ); + } + if (ReviewProgramEntity.ProvenanceLinks.Num() == 0 && !FirstRunRecordEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstRunRecordEntityId, + TEXT("chronicle-run-record"), + ReviewProgramEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + ReviewProgramEntity + ); + ReviewProgramEntityId = ReviewProgramEntity.EntityId; + } + + for (const FHyperTwistTrainingCoachSessionQueueState& QueueState : + RepositoryState.StoredCoachSessionQueues) + { + if (QueueState.UserId != UserId || QueueState.QueueId.IsEmpty()) + { + continue; + } + + const FHyperTwistTrainingCoachSessionQueueExecutionSummary QueueExecutionSummary = + UHyperTwistTrainingRepositoryLibrary::DeriveCoachSessionQueueExecutionSummary( + RepositoryState, + UserId, + QueueState.QueueId, + ResolvedReferenceUtc + ); + if (!QueueExecutionSummary.IsStructurallyValid()) + { + continue; + } + + FHyperTwistMemoryEntityDescriptor QueueExecutionEntity; + QueueExecutionEntity.EntityId = FString::Printf( + TEXT("memory-entity/shared-coordination/queue-execution-summary/%s"), + *QueueState.QueueId + ); + QueueExecutionEntity.RecordKind = TEXT("coach-session-queue-execution-summary"); + QueueExecutionEntity.DisplayLabel = TEXT("Coach Session Queue Execution Summary"); + QueueExecutionEntity.UserId = UserId; + QueueExecutionEntity.DeckId = QueueExecutionSummary.FocusDeckId; + QueueExecutionEntity.ReferenceUtc = QueueExecutionSummary.ReferenceUtc; + QueueExecutionEntity.Lane = EHyperTwistMemoryLane::SharedCoordination; + QueueExecutionEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::SemiAuthoritative; + QueueExecutionEntity.bDerived = true; + if (const FString* QueueEntityId = QueueEntityIdByQueueId.Find(QueueState.QueueId)) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + *QueueEntityId, + TEXT("queue-state"), + QueueExecutionEntity.ProvenanceLinks + ); + } + if (QueueExecutionEntity.ProvenanceLinks.Num() == 0 && !FirstQueueEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstQueueEntityId, + TEXT("queue-state"), + QueueExecutionEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + QueueExecutionEntity + ); + } + + const FHyperTwistTrainingCoachMemorySnapshot CoachMemorySnapshot = + UHyperTwistTrainingRepositoryLibrary::DeriveCoachMemorySnapshot( + RepositoryState, + UserId, + ResolvedReferenceUtc + ); + if (!CoachMemorySnapshot.UserId.IsEmpty() && !CoachMemorySnapshot.ReferenceUtc.IsEmpty()) + { + FHyperTwistMemoryEntityDescriptor CoachMemoryEntity; + CoachMemoryEntity.EntityId = FString::Printf( + TEXT("memory-entity/cognitive/coach-memory-snapshot/%s"), + *UserId + ); + CoachMemoryEntity.RecordKind = TEXT("coach-memory-snapshot"); + CoachMemoryEntity.DisplayLabel = TEXT("Coach Memory Snapshot"); + CoachMemoryEntity.UserId = UserId; + CoachMemoryEntity.DeckId = CoachMemorySnapshot.FocusDeckId; + CoachMemoryEntity.ReferenceUtc = CoachMemorySnapshot.ReferenceUtc; + CoachMemoryEntity.Lane = EHyperTwistMemoryLane::CognitiveConsolidated; + CoachMemoryEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::SemiAuthoritative; + CoachMemoryEntity.bDerived = true; + if (!ReviewProgramEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + ReviewProgramEntityId, + TEXT("review-program-summary"), + CoachMemoryEntity.ProvenanceLinks + ); + } + if (!CoachMemorySnapshot.WeakCaseIds.IsEmpty()) + { + const FString CaseKey = HyperTwistMemoryCoreLibraryInternal::MakeDeckCaseKey( + CoachMemorySnapshot.FocusDeckId, + CoachMemorySnapshot.WeakCaseIds[0] + ); + if (const FString* LearnerStateEntityId = LearnerStateEntityIdByDeckCaseKey.Find(CaseKey)) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + *LearnerStateEntityId, + TEXT("case-learner-state"), + CoachMemoryEntity.ProvenanceLinks + ); + } + } + if (CoachMemoryEntity.ProvenanceLinks.Num() == 0 && !FirstLearnerStateEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstLearnerStateEntityId, + TEXT("case-learner-state"), + CoachMemoryEntity.ProvenanceLinks + ); + } + if (!FirstCoachPlanEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstCoachPlanEntityId, + TEXT("coach-action-plan"), + CoachMemoryEntity.ProvenanceLinks + ); + } + if (CoachMemoryEntity.ProvenanceLinks.Num() == 0 && !FirstRunRecordEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstRunRecordEntityId, + TEXT("chronicle-run-record"), + CoachMemoryEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + CoachMemoryEntity + ); + CoachMemorySnapshotEntityId = CoachMemoryEntity.EntityId; + } + + const FHyperTwistTrainingCoachClosureMemorySummary CoachClosureSummary = + UHyperTwistTrainingRepositoryLibrary::DeriveCoachClosureMemorySummary( + RepositoryState, + UserId, + ResolvedReferenceUtc + ); + if (CoachClosureSummary.IsStructurallyValid()) + { + FHyperTwistMemoryEntityDescriptor CoachClosureEntity; + CoachClosureEntity.EntityId = FString::Printf( + TEXT("memory-entity/cognitive/coach-closure-memory-summary/%s"), + *UserId + ); + CoachClosureEntity.RecordKind = TEXT("coach-closure-memory-summary"); + CoachClosureEntity.DisplayLabel = TEXT("Coach Closure Memory Summary"); + CoachClosureEntity.UserId = UserId; + CoachClosureEntity.DeckId = CoachClosureSummary.FocusDeckId; + CoachClosureEntity.ReferenceUtc = CoachClosureSummary.ReferenceUtc; + CoachClosureEntity.Lane = EHyperTwistMemoryLane::CognitiveConsolidated; + CoachClosureEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::SemiAuthoritative; + CoachClosureEntity.bDerived = true; + if (const FString* CoachPlanEntityId = + CoachPlanEntityIdByPlanId.Find(CoachClosureSummary.FocusRootPlanId)) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + *CoachPlanEntityId, + TEXT("coach-action-plan"), + CoachClosureEntity.ProvenanceLinks + ); + } + if (CoachClosureEntity.ProvenanceLinks.Num() == 0 && !CoachMemorySnapshotEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + CoachMemorySnapshotEntityId, + TEXT("coach-memory-snapshot"), + CoachClosureEntity.ProvenanceLinks + ); + } + if (CoachClosureEntity.ProvenanceLinks.Num() == 0 && !FirstCoachPlanEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstCoachPlanEntityId, + TEXT("coach-action-plan"), + CoachClosureEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + CoachClosureEntity + ); + } + + const FHyperTwistTrainingCoachRecommendationHistorySummary RecommendationHistorySummary = + UHyperTwistTrainingRepositoryLibrary::DeriveCoachRecommendationHistorySummary( + RepositoryState, + UserId, + ResolvedReferenceUtc + ); + if (RecommendationHistorySummary.IsStructurallyValid()) + { + FHyperTwistMemoryEntityDescriptor RecommendationHistoryEntity; + RecommendationHistoryEntity.EntityId = FString::Printf( + TEXT("memory-entity/cognitive/coach-recommendation-history-summary/%s"), + *UserId + ); + RecommendationHistoryEntity.RecordKind = TEXT("coach-recommendation-history-summary"); + RecommendationHistoryEntity.DisplayLabel = TEXT("Coach Recommendation History Summary"); + RecommendationHistoryEntity.UserId = UserId; + RecommendationHistoryEntity.DeckId = RecommendationHistorySummary.FocusDeckId; + RecommendationHistoryEntity.ReferenceUtc = RecommendationHistorySummary.ReferenceUtc; + RecommendationHistoryEntity.Lane = EHyperTwistMemoryLane::CognitiveConsolidated; + RecommendationHistoryEntity.AuthorityKind = + EHyperTwistMemoryAuthorityKind::SemiAuthoritative; + RecommendationHistoryEntity.bDerived = true; + if (const FString* CoachPlanEntityId = + CoachPlanEntityIdByPlanId.Find(RecommendationHistorySummary.LatestPlanId)) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + *CoachPlanEntityId, + TEXT("coach-action-plan"), + RecommendationHistoryEntity.ProvenanceLinks + ); + } + if (RecommendationHistoryEntity.ProvenanceLinks.Num() == 0 && + !CoachMemorySnapshotEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + CoachMemorySnapshotEntityId, + TEXT("coach-memory-snapshot"), + RecommendationHistoryEntity.ProvenanceLinks + ); + } + if (RecommendationHistoryEntity.ProvenanceLinks.Num() == 0 && !FirstCoachPlanEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstCoachPlanEntityId, + TEXT("coach-action-plan"), + RecommendationHistoryEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + RecommendationHistoryEntity + ); + } + + const FHyperTwistTrainingCoachCarryForwardPolicySummary CarryForwardSummary = + UHyperTwistTrainingRepositoryLibrary::DeriveCoachCarryForwardPolicySummary( + RepositoryState, + UserId, + ResolvedReferenceUtc + ); + if (CarryForwardSummary.IsStructurallyValid()) + { + FHyperTwistMemoryEntityDescriptor CarryForwardEntity; + CarryForwardEntity.EntityId = FString::Printf( + TEXT("memory-entity/cognitive/coach-carry-forward-policy-summary/%s"), + *UserId + ); + CarryForwardEntity.RecordKind = TEXT("coach-carry-forward-policy-summary"); + CarryForwardEntity.DisplayLabel = TEXT("Coach Carry-Forward Policy Summary"); + CarryForwardEntity.UserId = UserId; + CarryForwardEntity.DeckId = CarryForwardSummary.FocusDeckId; + CarryForwardEntity.ReferenceUtc = CarryForwardSummary.ReferenceUtc; + CarryForwardEntity.Lane = EHyperTwistMemoryLane::CognitiveConsolidated; + CarryForwardEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::SemiAuthoritative; + CarryForwardEntity.bDerived = true; + if (!CoachMemorySnapshotEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + CoachMemorySnapshotEntityId, + TEXT("coach-memory-snapshot"), + CarryForwardEntity.ProvenanceLinks + ); + } + if (CarryForwardEntity.ProvenanceLinks.Num() == 0 && !FirstCoachPlanEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstCoachPlanEntityId, + TEXT("coach-action-plan"), + CarryForwardEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + CarryForwardEntity + ); + } + + const FHyperTwistTrainingCoachArchivePolicySummary ArchivePolicySummary = + UHyperTwistTrainingRepositoryLibrary::DeriveCoachArchivePolicySummary( + RepositoryState, + UserId, + ResolvedReferenceUtc + ); + if (ArchivePolicySummary.IsStructurallyValid()) + { + FHyperTwistMemoryEntityDescriptor ArchivePolicyEntity; + ArchivePolicyEntity.EntityId = FString::Printf( + TEXT("memory-entity/cognitive/coach-archive-policy-summary/%s"), + *UserId + ); + ArchivePolicyEntity.RecordKind = TEXT("coach-archive-policy-summary"); + ArchivePolicyEntity.DisplayLabel = TEXT("Coach Archive Policy Summary"); + ArchivePolicyEntity.UserId = UserId; + ArchivePolicyEntity.DeckId = ArchivePolicySummary.FocusDeckId; + ArchivePolicyEntity.ReferenceUtc = ArchivePolicySummary.ReferenceUtc; + ArchivePolicyEntity.Lane = EHyperTwistMemoryLane::CognitiveConsolidated; + ArchivePolicyEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::SemiAuthoritative; + ArchivePolicyEntity.bDerived = true; + if (!CoachMemorySnapshotEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + CoachMemorySnapshotEntityId, + TEXT("coach-memory-snapshot"), + ArchivePolicyEntity.ProvenanceLinks + ); + } + if (ArchivePolicyEntity.ProvenanceLinks.Num() == 0 && !FirstQueueEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstQueueEntityId, + TEXT("queue-state"), + ArchivePolicyEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + ArchivePolicyEntity + ); + } + + const FHyperTwistTrainingLearnerProfile LearnerProfile = + UHyperTwistTrainingRepositoryLibrary::DeriveLearnerProfile( + RepositoryState, + UserId, + ResolvedReferenceUtc + ); + if (!LearnerProfile.UserId.IsEmpty() && !LearnerProfile.ReferenceUtc.IsEmpty()) + { + FHyperTwistMemoryEntityDescriptor LearnerProfileEntity; + LearnerProfileEntity.EntityId = FString::Printf( + TEXT("memory-entity/compact/learner-profile/%s"), + *UserId + ); + LearnerProfileEntity.RecordKind = TEXT("learner-profile-summary"); + LearnerProfileEntity.DisplayLabel = TEXT("Learner Profile Summary"); + LearnerProfileEntity.UserId = UserId; + LearnerProfileEntity.DeckId = LearnerProfile.FavoriteDeckId; + LearnerProfileEntity.ReferenceUtc = LearnerProfile.ReferenceUtc; + LearnerProfileEntity.Lane = EHyperTwistMemoryLane::DerivedCompacted; + LearnerProfileEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::DerivedOnly; + LearnerProfileEntity.bDerived = true; + if (!FirstLearnerStateEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstLearnerStateEntityId, + TEXT("case-learner-state"), + LearnerProfileEntity.ProvenanceLinks + ); + } + if (LearnerProfileEntity.ProvenanceLinks.Num() == 0 && !FirstRunRecordEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + FirstRunRecordEntityId, + TEXT("chronicle-run-record"), + LearnerProfileEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + LearnerProfileEntity + ); + LearnerProfileEntityId = LearnerProfileEntity.EntityId; + } + + { + FHyperTwistMemoryEntityDescriptor LedgerOverviewEntity; + LedgerOverviewEntity.EntityId = FString::Printf( + TEXT("memory-entity/compact/ledger-overview/%s"), + *UserId + ); + LedgerOverviewEntity.RecordKind = TEXT("memory-ledger-overview"); + LedgerOverviewEntity.DisplayLabel = TEXT("Memory Ledger Overview"); + LedgerOverviewEntity.UserId = UserId; + LedgerOverviewEntity.ReferenceUtc = ResolvedReferenceUtc; + LedgerOverviewEntity.Lane = EHyperTwistMemoryLane::DerivedCompacted; + LedgerOverviewEntity.AuthorityKind = EHyperTwistMemoryAuthorityKind::DerivedOnly; + LedgerOverviewEntity.bDerived = true; + if (!LearnerProfileEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + LearnerProfileEntityId, + TEXT("learner-profile-summary"), + LedgerOverviewEntity.ProvenanceLinks + ); + } + if (!ReviewProgramEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + ReviewProgramEntityId, + TEXT("review-program-summary"), + LedgerOverviewEntity.ProvenanceLinks + ); + } + if (!CoachMemorySnapshotEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + CoachMemorySnapshotEntityId, + TEXT("coach-memory-snapshot"), + LedgerOverviewEntity.ProvenanceLinks + ); + } + if (LedgerOverviewEntity.ProvenanceLinks.Num() == 0 && !LedgerContractEntityId.IsEmpty()) + { + HyperTwistMemoryCoreLibraryInternal::TryAppendEntityProvenance( + EntitiesById, + LedgerContractEntityId, + TEXT("memory-ledger-contract"), + LedgerOverviewEntity.ProvenanceLinks + ); + } + + HyperTwistMemoryCoreLibraryInternal::AddEntity( + LedgerState, + EntitiesById, + LedgerOverviewEntity + ); + } + + return LedgerState; +} diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h index ccfe882..db99c4a 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h @@ -3,6 +3,7 @@ #include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "HyperTwistCore/HyperTwistCoreTypes.h" +#include "HyperTwistMemory/HyperTwistMemoryTypes.h" #include "HyperTwistRecognition/HyperTwistRecognitionReplayLibrary.h" #include "HyperTwistReplay/HyperTwistReplayTypes.h" #include "HyperTwistReplay/HyperTwistReplayReviewLibrary.h" @@ -141,6 +142,9 @@ public: UFUNCTION(BlueprintPure, Category = "HyperTwist|Training") static FHyperTwistTrainingRepositoryState MakeSampleTrainingRepositoryState(); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Memory") + static FHyperTwistMemoryLedgerState MakeSampleTrainingMemoryLedgerState(); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training") static FHyperTwistTrainingRepositoryIntegrityReport MakeSampleTrainingRepositoryIntegrityReport(); @@ -302,6 +306,9 @@ public: UFUNCTION(BlueprintPure, Category = "HyperTwist|Serialization") static FString SerializeTrainingRepositoryStateToJson(const FHyperTwistTrainingRepositoryState& RepositoryState); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Serialization") + static FString SerializeMemoryLedgerStateToJson(const FHyperTwistMemoryLedgerState& MemoryLedgerState); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Serialization") static FString SerializeTrainingTimerExportPacketToJson(const FHyperTwistTrainingTimerExportPacket& TimerExportPacket); @@ -341,6 +348,9 @@ public: UFUNCTION(BlueprintCallable, Category = "HyperTwist|Serialization") static bool DeserializeTrainingRepositoryStateFromJson(const FString& Json, FHyperTwistTrainingRepositoryState& OutRepositoryState); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Serialization") + static bool DeserializeMemoryLedgerStateFromJson(const FString& Json, FHyperTwistMemoryLedgerState& OutMemoryLedgerState); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Serialization") static bool DeserializeTrainingTimerExportPacketFromJson(const FString& Json, FHyperTwistTrainingTimerExportPacket& OutTimerExportPacket); }; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistMemory/HyperTwistMemoryCoreLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistMemory/HyperTwistMemoryCoreLibrary.h new file mode 100644 index 0000000..afadca5 --- /dev/null +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistMemory/HyperTwistMemoryCoreLibrary.h @@ -0,0 +1,21 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "HyperTwistMemory/HyperTwistMemoryTypes.h" +#include "HyperTwistTraining/HyperTwistTrainingTypes.h" +#include "HyperTwistMemoryCoreLibrary.generated.h" + +UCLASS() +class UNREALHYPERTWIST_API UHyperTwistMemoryCoreLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintPure, Category = "HyperTwist|Memory") + static FHyperTwistMemoryLedgerState DeriveMemoryLedgerState( + const FHyperTwistTrainingRepositoryState& RepositoryState, + const FString& UserId, + const FString& ReferenceUtc + ); +}; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistMemory/HyperTwistMemoryTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistMemory/HyperTwistMemoryTypes.h new file mode 100644 index 0000000..732834d --- /dev/null +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistMemory/HyperTwistMemoryTypes.h @@ -0,0 +1,329 @@ +#pragma once + +#include "CoreMinimal.h" +#include "HyperTwistMemoryTypes.generated.h" + +UENUM(BlueprintType) +enum class EHyperTwistMemoryLane : uint8 +{ + None UMETA(DisplayName = "None"), + IdentityPolicy UMETA(DisplayName = "Identity And Policy"), + WorkspaceRecall UMETA(DisplayName = "Workspace And Cockpit Recall"), + ChronicleCapture UMETA(DisplayName = "Chronicle And Episodic Capture"), + ContinuityResume UMETA(DisplayName = "Continuity And Resume"), + SharedCoordination UMETA(DisplayName = "Shared Coordination"), + RecallRetrieval UMETA(DisplayName = "Recall And Retrieval"), + CognitiveConsolidated UMETA(DisplayName = "Cognitive And Consolidated"), + KnowledgeWiki UMETA(DisplayName = "Knowledge And Wiki"), + UserNotes UMETA(DisplayName = "User Notes"), + ProvenanceLedger UMETA(DisplayName = "Provenance And Trust Ledger"), + DerivedCompacted UMETA(DisplayName = "Derived And Compacted"), + ProceduralWorkflow UMETA(DisplayName = "Procedural And Workflow") +}; + +UENUM(BlueprintType) +enum class EHyperTwistMemoryAuthorityKind : uint8 +{ + None UMETA(DisplayName = "None"), + Authoritative UMETA(DisplayName = "Authoritative"), + SemiAuthoritative UMETA(DisplayName = "Semi-Authoritative"), + DerivedOnly UMETA(DisplayName = "Derived Only") +}; + +UENUM(BlueprintType) +enum class EHyperTwistMemoryFeatureGateDefaultState : uint8 +{ + None UMETA(DisplayName = "None"), + RequiredEnabled UMETA(DisplayName = "Required Enabled"), + EnabledByDefault UMETA(DisplayName = "Enabled By Default"), + DisabledByDefault UMETA(DisplayName = "Disabled By Default") +}; + +UENUM(BlueprintType) +enum class EHyperTwistMemoryContextAssemblyProfile : uint8 +{ + None UMETA(DisplayName = "None"), + EconomicRetentionMode UMETA(DisplayName = "Economic-Retention Mode"), + MaxRetentionMode UMETA(DisplayName = "Max-Retention Mode") +}; + +USTRUCT(BlueprintType) +struct FHyperTwistMemoryProvenanceLink +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ParentEntityId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistMemoryLane ParentLane = EHyperTwistMemoryLane::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ParentRecordKind; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ParentReferenceUtc; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ParentSourceLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bParentAuthoritative = false; + + bool IsStructurallyValid() const + { + return !ParentEntityId.IsEmpty() + && ParentLane != EHyperTwistMemoryLane::None + && !ParentRecordKind.IsEmpty(); + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistMemoryFeatureGate +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString GateId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SettingsKey; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DisplayLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistMemoryLane Lane = EHyperTwistMemoryLane::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistMemoryFeatureGateDefaultState DefaultState = + EHyperTwistMemoryFeatureGateDefaultState::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bUserControllable = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bDisableAllowed = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Summary; + + bool IsStructurallyValid() const + { + return !GateId.IsEmpty() + && !SettingsKey.IsEmpty() + && Lane != EHyperTwistMemoryLane::None + && DefaultState != EHyperTwistMemoryFeatureGateDefaultState::None; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistMemoryLaneContract +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistMemoryLane Lane = EHyperTwistMemoryLane::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString LaneId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DisplayLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistMemoryAuthorityKind AuthorityKind = EHyperTwistMemoryAuthorityKind::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DefaultSettingsKey; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DefaultFeatureGateId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bFirstPartyOwned = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bCurrentEvidencePresent = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Summary; + + bool IsStructurallyValid() const + { + return Lane != EHyperTwistMemoryLane::None + && !LaneId.IsEmpty() + && !DisplayLabel.IsEmpty() + && AuthorityKind != EHyperTwistMemoryAuthorityKind::None + && !DefaultSettingsKey.IsEmpty() + && !DefaultFeatureGateId.IsEmpty(); + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistMemoryEntityDescriptor +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString EntityId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RecordKind; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DisplayLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString UserId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DeckId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ReferenceUtc; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistMemoryLane Lane = EHyperTwistMemoryLane::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistMemoryAuthorityKind AuthorityKind = EHyperTwistMemoryAuthorityKind::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bDerived = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray ProvenanceLinks; + + bool IsStructurallyValid() const + { + if (EntityId.IsEmpty() + || RecordKind.IsEmpty() + || DisplayLabel.IsEmpty() + || UserId.IsEmpty() + || Lane == EHyperTwistMemoryLane::None + || AuthorityKind == EHyperTwistMemoryAuthorityKind::None) + { + return false; + } + + for (const FHyperTwistMemoryProvenanceLink& ProvenanceLink : ProvenanceLinks) + { + if (!ProvenanceLink.IsStructurallyValid()) + { + return false; + } + } + + return !bDerived || ProvenanceLinks.Num() > 0; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistMemorySettingsProfile +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ProfileId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DisplayLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistMemoryContextAssemblyProfile ContextAssemblyProfile = + EHyperTwistMemoryContextAssemblyProfile::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray EnabledFeatureGateIds; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray DisabledFeatureGateIds; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Summary; + + bool IsStructurallyValid() const + { + return !ProfileId.IsEmpty() + && !DisplayLabel.IsEmpty() + && ContextAssemblyProfile != EHyperTwistMemoryContextAssemblyProfile::None; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistMemoryLedgerState +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString UserId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ReferenceUtc; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray LaneContracts; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray FeatureGates; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray Entities; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FHyperTwistMemorySettingsProfile EconomicRetentionProfile; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FHyperTwistMemorySettingsProfile MaxRetentionProfile; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AuthoritativeEntityCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SemiAuthoritativeEntityCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 DerivedEntityCount = 0; + + bool IsStructurallyValid() const + { + if (UserId.IsEmpty() + || ReferenceUtc.IsEmpty() + || LaneContracts.Num() == 0 + || FeatureGates.Num() == 0 + || !EconomicRetentionProfile.IsStructurallyValid() + || !MaxRetentionProfile.IsStructurallyValid()) + { + return false; + } + + for (const FHyperTwistMemoryLaneContract& LaneContract : LaneContracts) + { + if (!LaneContract.IsStructurallyValid()) + { + return false; + } + } + + for (const FHyperTwistMemoryFeatureGate& FeatureGate : FeatureGates) + { + if (!FeatureGate.IsStructurallyValid()) + { + return false; + } + } + + for (const FHyperTwistMemoryEntityDescriptor& Entity : Entities) + { + if (!Entity.IsStructurallyValid()) + { + return false; + } + } + + const int32 TotalEntityCount = + AuthoritativeEntityCount + SemiAuthoritativeEntityCount + DerivedEntityCount; + return TotalEntityCount == Entities.Num(); + } +}; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistMemoryPhase6RM1LedgerContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistMemoryPhase6RM1LedgerContractTest.cpp new file mode 100644 index 0000000..4cc3e3c --- /dev/null +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistMemoryPhase6RM1LedgerContractTest.cpp @@ -0,0 +1,190 @@ +// Copyright HyperTwist, Inc. All Rights Reserved. + +#include "Misc/AutomationTest.h" + +#include "HyperTwistBootstrap/HyperTwistContractLibrary.h" + +#if WITH_AUTOMATION_TESTS + +namespace HyperTwistMemoryPhase6RM1TestInternal +{ + const FHyperTwistMemoryLaneContract* FindLaneContract( + const FHyperTwistMemoryLedgerState& LedgerState, + const EHyperTwistMemoryLane Lane + ) + { + for (const FHyperTwistMemoryLaneContract& LaneContract : LedgerState.LaneContracts) + { + if (LaneContract.Lane == Lane) + { + return &LaneContract; + } + } + + return nullptr; + } + + const FHyperTwistMemoryEntityDescriptor* FindEntityByRecordKind( + const FHyperTwistMemoryLedgerState& LedgerState, + const FString& RecordKind + ) + { + for (const FHyperTwistMemoryEntityDescriptor& Entity : LedgerState.Entities) + { + if (Entity.RecordKind == RecordKind) + { + return &Entity; + } + } + + return nullptr; + } +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistMemoryPhase6RM1LaneContractsTest, + "HyperTwist.FirstParty.Memory.Phase6R.M1.LaneContracts", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistMemoryPhase6RM1LaneContractsTest::RunTest(const FString& Parameters) +{ + const FHyperTwistMemoryLedgerState LedgerState = + UHyperTwistContractLibrary::MakeSampleTrainingMemoryLedgerState(); + + TestTrue(TEXT("The Phase 6R-M1 memory ledger must be structurally valid."), LedgerState.IsStructurallyValid()); + TestEqual(TEXT("The Phase 6R-M1 ledger must expose all memory lane contracts."), LedgerState.LaneContracts.Num(), 12); + TestEqual(TEXT("The Phase 6R-M1 ledger must expose one feature gate per lane."), LedgerState.FeatureGates.Num(), 12); + TestEqual(TEXT("The economic retention profile id must stay canonical."), LedgerState.EconomicRetentionProfile.ProfileId, TEXT("memory-profile/economic-retention")); + TestEqual(TEXT("The max retention profile id must stay canonical."), LedgerState.MaxRetentionProfile.ProfileId, TEXT("memory-profile/max-retention")); + TestEqual(TEXT("The economic retention profile must stay canonical."), LedgerState.EconomicRetentionProfile.ContextAssemblyProfile, EHyperTwistMemoryContextAssemblyProfile::EconomicRetentionMode); + TestEqual(TEXT("The max retention profile must stay canonical."), LedgerState.MaxRetentionProfile.ContextAssemblyProfile, EHyperTwistMemoryContextAssemblyProfile::MaxRetentionMode); + + const FHyperTwistMemoryLaneContract* ChronicleLane = + HyperTwistMemoryPhase6RM1TestInternal::FindLaneContract( + LedgerState, + EHyperTwistMemoryLane::ChronicleCapture + ); + TestNotNull(TEXT("The chronicle lane contract must exist."), ChronicleLane); + if (ChronicleLane != nullptr) + { + TestEqual(TEXT("The chronicle lane id must stay canonical."), ChronicleLane->LaneId, TEXT("memory-lane/chronicle-capture")); + TestEqual(TEXT("The chronicle lane must remain authoritative."), ChronicleLane->AuthorityKind, EHyperTwistMemoryAuthorityKind::Authoritative); + } + + const FHyperTwistMemoryLaneContract* SharedCoordinationLane = + HyperTwistMemoryPhase6RM1TestInternal::FindLaneContract( + LedgerState, + EHyperTwistMemoryLane::SharedCoordination + ); + TestNotNull(TEXT("The shared coordination lane contract must exist."), SharedCoordinationLane); + if (SharedCoordinationLane != nullptr) + { + TestEqual(TEXT("The shared coordination lane id must stay canonical."), SharedCoordinationLane->LaneId, TEXT("memory-lane/shared-coordination")); + TestEqual(TEXT("The shared coordination lane must remain semi-authoritative."), SharedCoordinationLane->AuthorityKind, EHyperTwistMemoryAuthorityKind::SemiAuthoritative); + } + + const FHyperTwistMemoryLaneContract* DerivedLane = + HyperTwistMemoryPhase6RM1TestInternal::FindLaneContract( + LedgerState, + EHyperTwistMemoryLane::DerivedCompacted + ); + TestNotNull(TEXT("The derived-compacted lane contract must exist."), DerivedLane); + if (DerivedLane != nullptr) + { + TestEqual(TEXT("The derived-compacted lane id must stay canonical."), DerivedLane->LaneId, TEXT("memory-lane/derived-compacted")); + TestEqual(TEXT("The derived-compacted lane must remain derived-only."), DerivedLane->AuthorityKind, EHyperTwistMemoryAuthorityKind::DerivedOnly); + } + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistMemoryPhase6RM1DerivedProvenanceTest, + "HyperTwist.FirstParty.Memory.Phase6R.M1.DerivedProvenance", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistMemoryPhase6RM1DerivedProvenanceTest::RunTest(const FString& Parameters) +{ + const FHyperTwistMemoryLedgerState LedgerState = + UHyperTwistContractLibrary::MakeSampleTrainingMemoryLedgerState(); + + TestTrue(TEXT("The Phase 6R-M1 memory ledger must be structurally valid."), LedgerState.IsStructurallyValid()); + TestTrue(TEXT("The memory ledger must expose authoritative entities."), LedgerState.AuthoritativeEntityCount > 0); + TestTrue(TEXT("The memory ledger must expose semi-authoritative entities."), LedgerState.SemiAuthoritativeEntityCount > 0); + TestTrue(TEXT("The memory ledger must expose derived entities."), LedgerState.DerivedEntityCount > 0); + + const FHyperTwistMemoryEntityDescriptor* LearnerStateEntity = + HyperTwistMemoryPhase6RM1TestInternal::FindEntityByRecordKind( + LedgerState, + TEXT("case-learner-state") + ); + TestNotNull(TEXT("A semi-authoritative case learner-state entity must exist."), LearnerStateEntity); + if (LearnerStateEntity != nullptr) + { + TestEqual(TEXT("The case learner-state entity must remain in the cognitive lane."), LearnerStateEntity->Lane, EHyperTwistMemoryLane::CognitiveConsolidated); + TestEqual(TEXT("The case learner-state entity must remain semi-authoritative."), LearnerStateEntity->AuthorityKind, EHyperTwistMemoryAuthorityKind::SemiAuthoritative); + TestTrue(TEXT("The case learner-state entity must remain derived from chronicle evidence."), LearnerStateEntity->bDerived); + TestTrue(TEXT("The case learner-state entity must preserve provenance."), LearnerStateEntity->ProvenanceLinks.Num() > 0); + } + + const FHyperTwistMemoryEntityDescriptor* ReviewProgramEntity = + HyperTwistMemoryPhase6RM1TestInternal::FindEntityByRecordKind( + LedgerState, + TEXT("review-program-summary") + ); + TestNotNull(TEXT("A review-program summary entity must exist."), ReviewProgramEntity); + if (ReviewProgramEntity != nullptr) + { + TestEqual(TEXT("The review-program summary must remain in the recall lane."), ReviewProgramEntity->Lane, EHyperTwistMemoryLane::RecallRetrieval); + TestEqual(TEXT("The review-program summary must remain semi-authoritative."), ReviewProgramEntity->AuthorityKind, EHyperTwistMemoryAuthorityKind::SemiAuthoritative); + TestTrue(TEXT("The review-program summary must preserve provenance."), ReviewProgramEntity->ProvenanceLinks.Num() > 0); + } + + const FHyperTwistMemoryEntityDescriptor* LearnerProfileEntity = + HyperTwistMemoryPhase6RM1TestInternal::FindEntityByRecordKind( + LedgerState, + TEXT("learner-profile-summary") + ); + TestNotNull(TEXT("A learner-profile summary entity must exist."), LearnerProfileEntity); + if (LearnerProfileEntity != nullptr) + { + TestEqual(TEXT("The learner-profile summary must remain in the derived lane."), LearnerProfileEntity->Lane, EHyperTwistMemoryLane::DerivedCompacted); + TestEqual(TEXT("The learner-profile summary must remain derived-only."), LearnerProfileEntity->AuthorityKind, EHyperTwistMemoryAuthorityKind::DerivedOnly); + TestTrue(TEXT("The learner-profile summary must preserve provenance."), LearnerProfileEntity->ProvenanceLinks.Num() > 0); + } + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistMemoryPhase6RM1SerializationRoundTripTest, + "HyperTwist.FirstParty.Memory.Phase6R.M1.SerializationRoundTrip", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistMemoryPhase6RM1SerializationRoundTripTest::RunTest(const FString& Parameters) +{ + const FHyperTwistMemoryLedgerState LedgerState = + UHyperTwistContractLibrary::MakeSampleTrainingMemoryLedgerState(); + TestTrue(TEXT("The Phase 6R-M1 memory ledger must be structurally valid."), LedgerState.IsStructurallyValid()); + + const FString Json = UHyperTwistContractLibrary::SerializeMemoryLedgerStateToJson(LedgerState); + TestFalse(TEXT("The serialized memory ledger JSON must not be empty."), Json.IsEmpty()); + TestTrue(TEXT("The serialized memory ledger JSON must expose the chronicle lane id."), Json.Contains(TEXT("memory-lane/chronicle-capture"))); + + FHyperTwistMemoryLedgerState RoundTrippedLedgerState; + TestTrue(TEXT("The memory ledger JSON must deserialize cleanly."), UHyperTwistContractLibrary::DeserializeMemoryLedgerStateFromJson(Json, RoundTrippedLedgerState)); + TestTrue(TEXT("The round-tripped memory ledger must remain structurally valid."), RoundTrippedLedgerState.IsStructurallyValid()); + TestEqual(TEXT("The round-tripped memory ledger must preserve lane counts."), RoundTrippedLedgerState.LaneContracts.Num(), LedgerState.LaneContracts.Num()); + TestEqual(TEXT("The round-tripped memory ledger must preserve entity counts."), RoundTrippedLedgerState.Entities.Num(), LedgerState.Entities.Num()); + TestEqual(TEXT("The round-tripped memory ledger must preserve authoritative counts."), RoundTrippedLedgerState.AuthoritativeEntityCount, LedgerState.AuthoritativeEntityCount); + TestEqual(TEXT("The round-tripped memory ledger must preserve semi-authoritative counts."), RoundTrippedLedgerState.SemiAuthoritativeEntityCount, LedgerState.SemiAuthoritativeEntityCount); + TestEqual(TEXT("The round-tripped memory ledger must preserve derived counts."), RoundTrippedLedgerState.DerivedEntityCount, LedgerState.DerivedEntityCount); + TestEqual(TEXT("The round-tripped memory ledger must preserve the economic profile id."), RoundTrippedLedgerState.EconomicRetentionProfile.ProfileId, LedgerState.EconomicRetentionProfile.ProfileId); + TestEqual(TEXT("The round-tripped memory ledger must preserve the max profile id."), RoundTrippedLedgerState.MaxRetentionProfile.ProfileId, LedgerState.MaxRetentionProfile.ProfileId); + return true; +} + +#endif diff --git a/docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_IMPLEMENTATION_PACKET_2026-05-28.md b/docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_IMPLEMENTATION_PACKET_2026-05-28.md new file mode 100644 index 0000000..ee0ff60 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_IMPLEMENTATION_PACKET_2026-05-28.md @@ -0,0 +1,142 @@ +# HyperTwist Phase 6R-M1 first-party memory contracts and ledger implementation packet + +Created on `2026-05-28` + +## Status + +- first-party HyperTwist packet +- bounded `Phase 6R-M1` implementation slice + +## Purpose + +This packet lands the first bounded first-party memory implementation slice +under the canonical `Memory Lanes` doctrine. + +The landed slice is: + +- first-party memory contracts and ledger + +It is not: + +- a broad memory federation packet +- a chronicle/session-grouping packet +- a continuity/resume packet +- a recall/history-search packet +- a shared-context widening packet +- a cognitive extraction packet +- a knowledge-promotion or user-notes packet +- a compact reducer/digest packet + +## Current authority basis + +This implementation packet stands on: + +- `docs/ops/HYPERTWIST_MEMORY_LANE_AUTHORITY_AND_PHASE_IMPLEMENTATION_DOCTRINE_2026-05-21.md` +- `docs/ops/HYPERTWIST_CONTINUITY_LATTICE_AND_CONTEXT_ASSEMBLY_PROFILE_DOCTRINE_2026-05-23.md` +- `docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md` +- `docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md` +- `docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md` +- `docs/v6_5_deep_manual_pack/HyperTwist/PROVENANCE_AND_TRUST_MODEL.md` +- `docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_PREPARATION_PACKET_2026-05-28.md` + +The preserved owners do not change: + +- first-party HyperTwist remains the top-level owner for live memory-lane + contracts and memory-ledger product surfaces +- current training, replay, coaching, and repository code remains the raw + evidence substrate beneath this packet +- the VectorShell memory doctrine remains the external synchronization + entrypoint and authority map, not a frozen imported implementation + +## Landed scope + +The current code now owns a bounded first-party memory-contract and +memory-ledger seam through: + +- canonical memory lane, provenance, entity, feature-gate, retention-profile, + and ledger state types in: + - `HyperTwistMemoryTypes.h` +- first-party ledger derivation from current training repository state in: + - `UHyperTwistMemoryCoreLibrary` +- current bounded lane and control surfaces for: + - `12` memory lane contracts + - `12` feature gates + - `Economic-Retention Mode` + - `Max-Retention Mode` +- current bounded entity-ledger coverage for: + - identity policy profile + - provenance ledger contract + - run records + - review plans + - session templates + - method-drill favorites + - method-drill batches + - coach action plans + - coach session queues + - learner states + - review-program summary + - coach session-queue execution summaries + - coach memory snapshot + - coach closure memory summary + - coach recommendation history summary + - coach carry-forward policy summary + - coach archive policy summary + - learner profile summary + - ledger overview +- bounded provenance links and authority counters for: + - authoritative entities + - semi-authoritative entities + - derived-only entities +- sample contract helpers in: + - `UHyperTwistContractLibrary::MakeSampleTrainingMemoryLedgerState()` + - `UHyperTwistContractLibrary::SerializeMemoryLedgerStateToJson(...)` + - `UHyperTwistContractLibrary::DeserializeMemoryLedgerStateFromJson(...)` +- sample repository-state repair so review-program summary evidence now exists + without recursive sample construction +- focused automation coverage in: + - `HyperTwistMemoryPhase6RM1LedgerContractTest.cpp` + +## Why this is still intentionally bounded + +This packet lands memory contracts and ledger only. + +Still deferred: + +- chronicle ledger, session grouping, and resume packs +- explicit recall/history search and shared-context widening +- cognitive extraction, contradiction handling, supersession, or confidence + decay +- curated knowledge-promotion flows +- user-authored notes +- derived compact reducers, digests, and reduced-context packets + +## Validation + +Build validation: + +- `UnrealHyperTwistEditor Win64 Development` + +Focused automation validation: + +- `HyperTwist.FirstParty.Memory.Phase6R.M1.LaneContracts` +- `HyperTwist.FirstParty.Memory.Phase6R.M1.DerivedProvenance` +- `HyperTwist.FirstParty.Memory.Phase6R.M1.SerializationRoundTrip` + +Non-blocking warnings stayed limited to the existing Unreal headless/editor +noise, expected Python-stub regeneration noise, headless CEF/web-browser +warnings, and benign asset-registry/cache journal chatter during editor +startup. + +## Queue effect + +This packet consumes the current `Phase 6R-M1` implementation slice. + +Memory implementation is now live at the contract/ledger layer through lane +ids, entity ids, provenance links, authority flags, feature-gate/settings +control, and retention-profile defaults. + +If later memory implementation continues: + +- the next clean move is `Phase 6R-M2` +- do not reopen `6R-M1` as one broad "memory packet" + diff --git a/docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_PREPARATION_PACKET_2026-05-28.md b/docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_PREPARATION_PACKET_2026-05-28.md new file mode 100644 index 0000000..a259fc7 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASE6R_M1_FIRST_PARTY_MEMORY_CONTRACTS_AND_LEDGER_PREPARATION_PACKET_2026-05-28.md @@ -0,0 +1,118 @@ +# HyperTwist Phase 6R-M1 first-party memory contracts and ledger preparation packet + +Created on `2026-05-28` + +## Status + +- first-party HyperTwist packet +- source-backed `Phase 6R-M1` preparation/control slice + +## Purpose + +This packet scopes the first bounded first-party memory implementation slice +under the canonical `Memory Lanes` doctrine. + +The granted slice is: + +- first-party memory contracts and ledger only + +It is not: + +- a broad memory federation packet +- a chronicle/session-grouping packet +- a continuity/resume packet +- a recall/history-search packet +- a shared-context widening packet +- a cognitive fact-extraction packet +- a knowledge-promotion or user-notes packet +- a compact reducer/digest packet + +## Current authority basis + +This control pass stands on: + +- `docs/ops/HYPERTWIST_MEMORY_LANE_AUTHORITY_AND_PHASE_IMPLEMENTATION_DOCTRINE_2026-05-21.md` +- `docs/ops/HYPERTWIST_CONTINUITY_LATTICE_AND_CONTEXT_ASSEMBLY_PROFILE_DOCTRINE_2026-05-23.md` +- `docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md` +- `docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md` +- `docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md` +- `docs/v6_5_deep_manual_pack/HyperTwist/PROVENANCE_AND_TRUST_MODEL.md` +- `docs/VECTORSHELL_MEMORY_SYSTEM_IMPORT_AUTHORITY_FOR_HYPERTWIST_2026-05-25.md` + +The preserved owners do not change here: + +- first-party HyperTwist remains the top-level owner for live memory-lane + contracts and memory-ledger product surfaces +- current training, replay, coaching, and repository code remains the raw + evidence substrate beneath this packet +- the VectorShell memory doctrine remains the external synchronization + entrypoint and authority map, not a frozen imported implementation + +## Granted family + +The bounded `Phase 6R-M1` slice may land: + +1. lane ids and lane contracts for the canonical first-party `Memory Lanes` +2. memory entity ids for current authoritative, semi-authoritative, and + derived product-memory objects over the live training repository state +3. provenance-link structures and ledger-visible parentage for non-raw memory + entities +4. authoritative-versus-derived flags and counts +5. settings keys, feature gates, and preset-backed retention-profile defaults + for: + - `Economic-Retention Mode` + - `Max-Retention Mode` +6. bounded sample contract and serialization coverage for the `6R-M1` ledger + surface + +The packet must stay out of: + +- chronicle grouping and resume-pack ownership +- explicit remember/recall search ownership +- scoped shared-context widening +- cognitive extraction, contradiction handling, or supersession +- curated knowledge-promotion flows +- user-authored notes +- compact reducers, digests, or reduced-context packets + +## Proposed implementation shape + +Land the narrower first-party boundary through: + +- new memory types for: + - lane contracts + - feature gates + - provenance links + - entity descriptors + - retention profiles + - bounded ledger state +- a first-party memory-core library that derives the ledger from current + repository state +- sample-contract helpers for: + - sample memory ledger creation + - JSON serialization + - JSON deserialization +- focused automation in: + - `HyperTwistMemoryPhase6RM1LedgerContractTest.cpp` + +## Validation target + +Validate with: + +- Unreal build for `UnrealHyperTwistEditor Win64 Development` +- focused automation: + - `HyperTwist.FirstParty.Memory.Phase6R.M1.LaneContracts` + - `HyperTwist.FirstParty.Memory.Phase6R.M1.DerivedProvenance` + - `HyperTwist.FirstParty.Memory.Phase6R.M1.SerializationRoundTrip` + +## Queue effect + +If this packet lands cleanly, HyperTwist memory no longer remains only a +retained doctrine surface at the contract layer. A first bounded live +first-party memory-ledger seam becomes current product truth. + +If later memory implementation continues: + +- the next clean move is `Phase 6R-M2` +- do not reopen `6R-M1` as one broad "memory packet" + diff --git a/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md b/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md index 9271ab2..c0dcf0b 100644 --- a/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md +++ b/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md @@ -222,6 +222,9 @@ The next bounded move is now: When HyperTwist later returns to memory implementation: +- the bounded first-party `Phase 6R-M1` memory contracts and ledger packet is + now landed in current code +- if memory implementation continues, the next clean move is `Phase 6R-M2` - do not open one broad "memory packet" - follow the lane map and packet order in `C:\HyperTwist\docs\ops\HYPERTWIST_MEMORY_LANE_AUTHORITY_AND_PHASE_IMPLEMENTATION_DOCTRINE_2026-05-21.md` diff --git a/docs/ops/HYPERTWIST_MEMORY_LANE_AUTHORITY_AND_PHASE_IMPLEMENTATION_DOCTRINE_2026-05-21.md b/docs/ops/HYPERTWIST_MEMORY_LANE_AUTHORITY_AND_PHASE_IMPLEMENTATION_DOCTRINE_2026-05-21.md index e0c752b..575da69 100644 --- a/docs/ops/HYPERTWIST_MEMORY_LANE_AUTHORITY_AND_PHASE_IMPLEMENTATION_DOCTRINE_2026-05-21.md +++ b/docs/ops/HYPERTWIST_MEMORY_LANE_AUTHORITY_AND_PHASE_IMPLEMENTATION_DOCTRINE_2026-05-21.md @@ -643,6 +643,15 @@ Implement: - authoritative-versus-derived flags - settings keys and feature gates +Current standing: + +- the bounded first-party `Phase 6R-M1` memory contracts and ledger packet is + now landed in current code +- current live `6R-M1` surfaces cover lane ids, memory entity ids, provenance + links, authority flags, feature gates, retention profiles, and bounded + ledger serialization +- if memory implementation continues, the next clean move is `6R-M2` + ### `6R-M2` - chronicle and continuity packet Implement: diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md b/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md index e94dec8..3efb19b 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md @@ -179,6 +179,8 @@ That means: - one federated substrate - bounded `Memory Lanes` +- a live first-party `Phase 6R-M1` contract/ledger layer over current memory + evidence surfaces - explicit provenance - explicit custody - two context-assembly profiles: diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md index a887658..9e53058 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md @@ -287,6 +287,7 @@ repo. |---|---|---|---| | Session continuity and workspace recall fragments | Implemented now | first-party runtime/training surfaces | Real substrate fragments under the canonical `Memory Lanes`; not yet a full lane implementation. | | Provenance-aware training/replay/publication state | Implemented now | first-party contract/provenance surfaces | Existing product truth. | +| First-party memory contracts and ledger | Implemented now | landed first-party `Phase 6R-M1` packet | Current bounded memory lane ids, entity ids, provenance links, authority flags, feature gates, retention profiles, and ledger JSON round-trip are live. Chronicle/resume, recall/shared context, cognitive extraction, knowledge/notes, and compact reducers stay deferred to later memory packets. | | Control-plane telemetry, replay-diagnostic, and rollout-governance reference grounding | Implemented now | `PostHog/posthog` retained boundary-sensitive lane + first-party current code | Current live `Control-Plane Telemetry and Replay Governance` reference side includes six rewritten first-party contract/reference targets grounded in `PostHog/posthog`: replay diagnostics, replay segmentation, feature governance, scheduled changes, early-access lifecycle, and explicit `MIT`-outside-`ee/` compliance-boundary notes. This does not displace the landed `Phase 4R-D` first-party owner lane, any replay-shell owner family, or the explicit enterprise-subtree exclusion boundary. | | Capture-history, vault, and replay-inspection reference grounding | Implemented now | `screenpipe/screenpipe` retained boundary-sensitive lane + first-party current code | Current live `Capture History, Replay, and Vault Support` reference side includes six rewritten first-party contract/reference targets grounded in `screenpipe/screenpipe`: event-capture, pipe-permission, persistence, vault-lifecycle, timeline-review, and explicit permissive-core-versus-`ee/` compliance-boundary notes. This does not displace the landed `Phase 4R-E` first-party owner lane, the broader replay shell, or the explicit enterprise-subtree exclusion boundary. | | Layered memory federation | Deep-source grounded retained | memory doctrine + VectorShell import entrypoint | Governing taxonomy exists; HyperTwist uses pointer-based synchronization to the current VectorShell memory canon rather than a frozen local fork. Lane widening remains future work and later superior evidence may revise only the exact affected lane or sub-slice. | diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/PROVENANCE_AND_TRUST_MODEL.md b/docs/v6_5_deep_manual_pack/HyperTwist/PROVENANCE_AND_TRUST_MODEL.md index 5ce31e8..506428e 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/PROVENANCE_AND_TRUST_MODEL.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/PROVENANCE_AND_TRUST_MODEL.md @@ -95,6 +95,8 @@ Companion extraction surface: The memory doctrine defines provenance/trust-ledger memory as a distinct lane and requires provenance to survive: +- the landed bounded first-party `Phase 6R-M1` memory contracts and ledger + packet - chronicle capture - continuity/resume packets - cognitive coach-state consolidation diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md index a435969..9266bf0 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md @@ -131,6 +131,12 @@ Canonical discovery surfaces for roadmap interpretation: - the continuity-profile sync now names `Continuity Lattice` as the substrate only, keeps `Memory Lanes` canonical, and treats `Max-Retention Mode` and `Economic-Retention Mode` as preset-backed overrideable context-assembly profiles rather than a second memory system +- the generic first-party `Phase 6R-M1` memory contracts and ledger control pass is now + consumed +- the bounded first-party `Phase 6R-M1` memory contracts and ledger packet is now landed in + current code +- if memory implementation continues, the next clean move is `Phase 6R-M2` chronicle and + continuity rather than reopening `6R-M1` as a broad memory packet - the generic source-backed `Phase 6R-R` shared classic-cube recognition multi-face correction/explanation control pass is now consumed - the bounded permissive `Phase 6R-R` shared classic-cube recognition multi-face