From eac1c6dce9566765248956101f2b4c009a440e11 Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Fri, 29 May 2026 05:48:11 +0200 Subject: [PATCH] Implement Phase S3-C workflow-memory capture skills --- .../HyperTwistContractLibrary.cpp | 53 +++ .../HyperTwistSkillCoreLibrary.cpp | 384 +++++++++++++++++- .../HyperTwistContractLibrary.h | 15 + .../HyperTwistSkillCoreLibrary.h | 9 + .../HyperTwistSkills/HyperTwistSkillTypes.h | 273 +++++++++++++ ...llPhaseS1ARegistryManifestContractTest.cpp | 39 +- ...seS1CInvocationAuditLedgerContractTest.cpp | 27 +- ...AuthoringValidationHarnessContractTest.cpp | 38 ++ ...seS3CWorkflowMemoryCaptureContractTest.cpp | 199 +++++++++ ...SKILLS_IMPLEMENTATION_PACKET_2026-05-29.md | 36 ++ ...RE_SKILLS_PREPARATION_PACKET_2026-05-29.md | 39 ++ ...PERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md | 4 +- ...AND_COMMAND_SURFACE_DOCTRINE_2026-05-21.md | 14 +- .../HyperTwist/ARCHITECTURE.md | 5 + .../HyperTwist/FEATURE_REGISTRY.md | 4 +- .../HyperTwist/PROVENANCE_AND_TRUST_MODEL.md | 4 + .../HyperTwist/ROADMAP.md | 4 +- .../HyperTwist/SKILLS.md | 7 +- 18 files changed, 1136 insertions(+), 18 deletions(-) create mode 100644 UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS3CWorkflowMemoryCaptureContractTest.cpp create mode 100644 docs/arch/HYPERTWIST_PHASES3_C_FIRST_PARTY_WORKFLOW_MEMORY_CAPTURE_SKILLS_IMPLEMENTATION_PACKET_2026-05-29.md create mode 100644 docs/arch/HYPERTWIST_PHASES3_C_FIRST_PARTY_WORKFLOW_MEMORY_CAPTURE_SKILLS_PREPARATION_PACKET_2026-05-29.md diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp index 507ffc6..041b4bf 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp @@ -99,6 +99,22 @@ namespace HyperTwistContractLibraryInternal return OverrideState; }(), []() + { + FHyperTwistSkillControlOverride OverrideState; + OverrideState.SkillId = TEXT("skill/capture-session-template"); + OverrideState.bHasEnabledOverride = true; + OverrideState.bEnabled = true; + return OverrideState; + }(), + []() + { + FHyperTwistSkillControlOverride OverrideState; + OverrideState.SkillId = TEXT("skill/capture-follow-up-routine"); + OverrideState.bHasEnabledOverride = true; + OverrideState.bEnabled = true; + return OverrideState; + }(), + []() { FHyperTwistSkillControlOverride OverrideState; OverrideState.SkillId = TEXT("skill/provider-routing-inspector"); @@ -4132,6 +4148,23 @@ UHyperTwistContractLibrary::MakeSampleSkillRecallCompactViewState() ); } +FHyperTwistSkillWorkflowMemoryCaptureState +UHyperTwistContractLibrary::MakeSampleSkillWorkflowMemoryCaptureState() +{ + const FHyperTwistSkillRegistryState RegistryState = MakeSampleSkillRegistryState(); + const FHyperTwistSkillControlState ControlState = MakeSampleSkillControlState(); + const FHyperTwistSkillAuthoringHarnessState AuthoringHarnessState = + MakeSampleSkillAuthoringHarnessState(); + + return UHyperTwistSkillCoreLibrary::DeriveSkillWorkflowMemoryCaptureState( + RegistryState, + ControlState, + AuthoringHarnessState, + MakeSampleTrainingMemoryLedgerState(), + MakeSampleTrainingMemoryChronicleContinuityState() + ); +} + FHyperTwistTrainingRepositoryIntegrityReport UHyperTwistContractLibrary::MakeSampleTrainingRepositoryIntegrityReport() { FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); @@ -5322,6 +5355,15 @@ FString UHyperTwistContractLibrary::SerializeSkillRecallCompactViewStateToJson( ); } +FString UHyperTwistContractLibrary::SerializeSkillWorkflowMemoryCaptureStateToJson( + const FHyperTwistSkillWorkflowMemoryCaptureState& SkillWorkflowMemoryCaptureState +) +{ + return HyperTwistContractLibraryInternal::SerializeStructToJson( + SkillWorkflowMemoryCaptureState + ); +} + FString UHyperTwistContractLibrary::SerializeTrainingTimerExportPacketToJson( const FHyperTwistTrainingTimerExportPacket& TimerExportPacket ) @@ -5543,6 +5585,17 @@ bool UHyperTwistContractLibrary::DeserializeSkillRecallCompactViewStateFromJson( ); } +bool UHyperTwistContractLibrary::DeserializeSkillWorkflowMemoryCaptureStateFromJson( + const FString& Json, + FHyperTwistSkillWorkflowMemoryCaptureState& OutSkillWorkflowMemoryCaptureState +) +{ + return HyperTwistContractLibraryInternal::DeserializeStructFromJson( + Json, + OutSkillWorkflowMemoryCaptureState + ); +} + bool UHyperTwistContractLibrary::DeserializeTrainingTimerExportPacketFromJson( const FString& Json, FHyperTwistTrainingTimerExportPacket& OutTimerExportPacket diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistSkills/HyperTwistSkillCoreLibrary.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistSkills/HyperTwistSkillCoreLibrary.cpp index 808684d..9f64cf6 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistSkills/HyperTwistSkillCoreLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistSkills/HyperTwistSkillCoreLibrary.cpp @@ -445,6 +445,12 @@ namespace HyperTwistSkillCoreLibraryInternal || SkillId == TEXT("skill/generate-compact-view"); } + bool IsWorkflowMemoryCaptureSkill(const FString& SkillId) + { + return SkillId == TEXT("skill/capture-session-template") + || SkillId == TEXT("skill/capture-follow-up-routine"); + } + bool HasAtLeastCleanRoomCommandContractStatus(const EHyperTwistSkillStatus Status) { return Status == EHyperTwistSkillStatus::CleanRoomCommandContractSpecified @@ -666,6 +672,12 @@ namespace HyperTwistSkillCoreLibraryInternal return EHyperTwistSkillInvocationOutcome::Succeeded; } + if (Entry.SkillId == TEXT("skill/capture-session-template") + || Entry.SkillId == TEXT("skill/capture-follow-up-routine")) + { + return EHyperTwistSkillInvocationOutcome::Succeeded; + } + return EHyperTwistSkillInvocationOutcome::Failed; } @@ -962,11 +974,11 @@ namespace HyperTwistSkillCoreLibraryInternal FHyperTwistSkillRegistryState RegistryState; RegistryState.RegistryId = TEXT("skill-registry/first-party"); - RegistryState.ManifestVersion = TEXT("s3b-v1"); - RegistryState.ReferenceUtc = TEXT("2026-05-29T03:40:00Z"); + RegistryState.ManifestVersion = TEXT("s3c-v1"); + RegistryState.ReferenceUtc = TEXT("2026-05-29T07:10:00Z"); RegistryState.CommandSurfaceRootId = TEXT("command-surface/skills"); RegistryState.Summary = - TEXT("First-party skill registry and manifest contract with landed permissive analyzer wrappers, landed clean-room command contracts, landed clean-room skill specs, landed continuity/resume skills, and landed recall/compact-view skills."); + TEXT("First-party skill registry and manifest contract with landed permissive analyzer wrappers, landed clean-room command contracts, landed clean-room skill specs, landed continuity/resume skills, landed recall/compact-view skills, and landed workflow-memory capture skills."); RegistryState.Entries = { MakeSkillEntry( @@ -1300,6 +1312,88 @@ namespace HyperTwistSkillCoreLibraryInternal ), TEXT("Landed first-party optional compact-view skill over derived memory adjunct surfaces.") ), + MakeSkillEntry( + TEXT("skill/capture-session-template"), + TEXT("Capture Session Template"), + TEXT("lane/skillization/memory-continuity"), + TEXT("feature/skills/capture-session-template"), + EHyperTwistSkillFamily::MemoryContinuity, + EHyperTwistSkillStatus::ImplementedNow, + false, + true, + { + MakeCommandBinding( + TEXT("command/skills/capture-session-template"), + TEXT("service/skills/capture-session-template"), + TEXT("feature/skills/capture-session-template"), + TEXT("memory/workflow-template-capture"), + true, + TEXT("Live first-party workflow capture skill over authoritative session-template and drill-workflow entities.") + ) + }, + { + MakePermissionScope( + TEXT("scope/skills/capture-session-template"), + TEXT("Capture Session Template"), + true, + false, + false, + true, + false, + false, + true, + TEXT("Reads authoritative training and workflow memory state to emit bounded session-template capture output.") + ) + }, + MakeProvenanceDeclaration( + EHyperTwistSkillLogPolicy::InvocationLedgerRequired, + {TEXT("artifact/workflow-template-capture-brief")}, + true, + TEXT("Workflow-template capture output must remain provenance-visible, derived-only, and separate from user-authored notes.") + ), + TEXT("Landed first-party workflow capture skill over authoritative session-template and drill-workflow entities.") + ), + MakeSkillEntry( + TEXT("skill/capture-follow-up-routine"), + TEXT("Capture Follow-Up Routine"), + TEXT("lane/skillization/memory-continuity"), + TEXT("feature/skills/capture-follow-up-routine"), + EHyperTwistSkillFamily::MemoryContinuity, + EHyperTwistSkillStatus::ImplementedNow, + false, + true, + { + MakeCommandBinding( + TEXT("command/skills/capture-follow-up-routine"), + TEXT("service/skills/capture-follow-up-routine"), + TEXT("feature/skills/capture-follow-up-routine"), + TEXT("memory/workflow-follow-up-capture"), + true, + TEXT("Live first-party workflow capture skill over authoritative review-plan, coach-action-plan, and queue follow-up entities.") + ) + }, + { + MakePermissionScope( + TEXT("scope/skills/capture-follow-up-routine"), + TEXT("Capture Follow-Up Routine"), + true, + false, + false, + true, + false, + false, + true, + TEXT("Reads authoritative training and workflow memory state to emit bounded follow-up routine capture output.") + ) + }, + MakeProvenanceDeclaration( + EHyperTwistSkillLogPolicy::InvocationLedgerRequired, + {TEXT("artifact/follow-up-routine-capture-brief")}, + true, + TEXT("Follow-up routine capture output must remain provenance-visible, derived-only, and avoid opaque summary collapse.") + ), + TEXT("Landed first-party workflow capture skill over authoritative review-plan and follow-up routine entities.") + ), MakeSkillEntry( TEXT("skill/provider-routing-inspector"), TEXT("Provider Routing Inspector"), @@ -1447,7 +1541,7 @@ namespace HyperTwistSkillCoreLibraryInternal RegistryState.FamilyCounts = { MakeFamilyCount(EHyperTwistSkillFamily::SubstrateGovernance, 1), MakeFamilyCount(EHyperTwistSkillFamily::AnalysisReview, 1), - MakeFamilyCount(EHyperTwistSkillFamily::MemoryContinuity, 6), + MakeFamilyCount(EHyperTwistSkillFamily::MemoryContinuity, 8), MakeFamilyCount(EHyperTwistSkillFamily::ProviderOperations, 1), MakeFamilyCount(EHyperTwistSkillFamily::TrainingCoaching, 1), MakeFamilyCount(EHyperTwistSkillFamily::DomainCreative, 1) @@ -2644,3 +2738,285 @@ UHyperTwistSkillCoreLibrary::DeriveSkillRecallCompactViewState( return RecallCompactViewState; } + +FHyperTwistSkillWorkflowMemoryCaptureState +UHyperTwistSkillCoreLibrary::DeriveSkillWorkflowMemoryCaptureState( + const FHyperTwistSkillRegistryState& RegistryState, + const FHyperTwistSkillControlState& ControlState, + const FHyperTwistSkillAuthoringHarnessState& AuthoringHarnessState, + const FHyperTwistMemoryLedgerState& LedgerState, + const FHyperTwistMemoryChronicleContinuityState& ChronicleContinuityState +) +{ + using namespace HyperTwistSkillCoreLibraryInternal; + + if (!RegistryState.IsStructurallyValid() + || !ControlState.IsStructurallyValid() + || !AuthoringHarnessState.IsStructurallyValid() + || !LedgerState.IsStructurallyValid() + || !ChronicleContinuityState.IsStructurallyValid() + || RegistryState.RegistryId != ControlState.RegistryId + || RegistryState.RegistryId != AuthoringHarnessState.RegistryId + || RegistryState.CommandSurfaceRootId != ControlState.CommandSurfaceRootId + || RegistryState.CommandSurfaceRootId != AuthoringHarnessState.CommandSurfaceRootId) + { + return FHyperTwistSkillWorkflowMemoryCaptureState(); + } + + FHyperTwistSkillWorkflowMemoryCaptureState WorkflowCaptureState; + WorkflowCaptureState.RegistryId = RegistryState.RegistryId; + WorkflowCaptureState.ManifestVersion = TEXT("s3c-v1"); + WorkflowCaptureState.ReferenceUtc = TEXT("2026-05-29T07:30:00Z"); + WorkflowCaptureState.CommandSurfaceRootId = RegistryState.CommandSurfaceRootId; + WorkflowCaptureState.TemplateVersion = TEXT("skill-workflow-memory-capture-v1"); + WorkflowCaptureState.bEveryLiveSkillReadsAuthoritativeStores = true; + WorkflowCaptureState.bEverySkillPreservesOptionalAssistiveOffState = true; + WorkflowCaptureState.bEveryLiveSkillHasValidationHarnessCoverage = true; + WorkflowCaptureState.bWorkflowMemoryRemainsSeparateFromUserAuthoredNotes = true; + WorkflowCaptureState.bWorkflowMemoryDoesNotCollapseIntoOpaqueSummaries = true; + WorkflowCaptureState.Summary = + TEXT("First-party workflow-memory capture skill layer over authoritative procedural and continuity seams."); + + auto AddPreviewHeadline = []( + TArray& PreviewHeadlines, + const FString& Headline + ) + { + if (!Headline.IsEmpty()) + { + PreviewHeadlines.AddUnique(Headline); + } + }; + + auto AddUniqueEntityId = []( + TArray& EntityIds, + const FString& EntityId + ) + { + if (!EntityId.IsEmpty()) + { + EntityIds.AddUnique(EntityId); + } + }; + + const bool bHasProceduralWorkflowLaneEvidence = LedgerState.LaneContracts.ContainsByPredicate( + [](const FHyperTwistMemoryLaneContract& LaneContract) + { + return LaneContract.Lane == EHyperTwistMemoryLane::ProceduralWorkflow + && LaneContract.AuthorityKind == EHyperTwistMemoryAuthorityKind::Authoritative + && LaneContract.bFirstPartyOwned + && LaneContract.bCurrentEvidencePresent; + } + ); + + auto BuildWorkflowSkill = [&]( + const FString& SkillId + ) -> FHyperTwistSkillWorkflowMemoryCaptureSkill + { + const FHyperTwistSkillManifestEntry* Entry = + FindManifestEntryById(RegistryState, SkillId); + const FHyperTwistSkillControlStateEntry* ControlEntry = + FindControlStateEntryById(ControlState, SkillId); + const FHyperTwistSkillAuthoringExampleState* ExampleState = + FindAuthoringExampleBySkillId(AuthoringHarnessState, SkillId); + if (Entry == nullptr + || !Entry->IsStructurallyValid() + || !IsWorkflowMemoryCaptureSkill(SkillId) + || ControlEntry == nullptr + || !ControlEntry->IsStructurallyValid() + || !ControlEntry->bInstalled + || !ControlEntry->bOptionalAssistive + || ExampleState == nullptr + || !ExampleState->IsStructurallyValid() + || !HasLiveEvalValidationCase(AuthoringHarnessState, SkillId)) + { + return FHyperTwistSkillWorkflowMemoryCaptureSkill(); + } + + FHyperTwistSkillWorkflowMemoryCaptureSkill SkillState; + SkillState.SkillId = Entry->SkillId; + SkillState.DisplayLabel = Entry->DisplayLabel; + SkillState.CommandSurfaceId = Entry->CommandBindings[0].CommandSurfaceId; + SkillState.ServiceBindingId = Entry->CommandBindings[0].ServiceBindingId; + SkillState.OwnerLaneId = Entry->OwnerLaneId; + SkillState.OwnerFeatureId = Entry->OwnerFeatureId; + SkillState.Status = Entry->Status; + SkillState.PermissionScopeIds = MakePermissionScopeIds(*Entry); + SkillState.OutputArtifactKinds = Entry->Provenance.ProducedArtifactKinds; + SkillState.bLiveSkill = true; + SkillState.bRequiresOwnerActivation = false; + SkillState.bPreservesOptionalAssistiveOffState = ControlEntry->bInertWhenDisabled; + SkillState.bDerivedAssistiveOnly = Entry->bOptionalAssistive; + SkillState.bHasValidationHarnessCoverage = true; + SkillState.bAvoidsUserAuthoredNoteCapture = true; + SkillState.bAvoidsOpaqueSummaryCollapse = true; + + TArray LinkedWorkflowEntityIds; + + if (SkillId == TEXT("skill/capture-session-template")) + { + SkillState.InputStateKinds = { + TEXT("state/memory-ledger"), + TEXT("state/memory-entity-descriptor"), + TEXT("state/memory-procedural-workflow-lane") + }; + + for (const FHyperTwistMemoryEntityDescriptor& Entity : LedgerState.Entities) + { + if (Entity.Lane != EHyperTwistMemoryLane::ProceduralWorkflow + || Entity.AuthorityKind != EHyperTwistMemoryAuthorityKind::Authoritative) + { + continue; + } + + if (Entity.RecordKind == TEXT("training-session-template") + || Entity.RecordKind == TEXT("method-drill-favorite") + || Entity.RecordKind == TEXT("method-drill-batch")) + { + AddPreviewHeadline(SkillState.PreviewHeadlines, Entity.DisplayLabel); + AddUniqueEntityId(LinkedWorkflowEntityIds, Entity.EntityId); + } + } + + SkillState.AvailableItemCount = LinkedWorkflowEntityIds.Num(); + SkillState.LinkedWorkflowEntityCount = LinkedWorkflowEntityIds.Num(); + SkillState.BlockingItemCount = 0; + SkillState.bReadsAuthoritativeStores = + bHasProceduralWorkflowLaneEvidence && LinkedWorkflowEntityIds.Num() > 0; + SkillState.bAvailableNow = LinkedWorkflowEntityIds.Num() > 0; + SkillState.Summary = + TEXT("Live first-party workflow capture skill over authoritative session-template and drill-workflow entities."); + } + else if (SkillId == TEXT("skill/capture-follow-up-routine")) + { + SkillState.InputStateKinds = { + TEXT("state/memory-ledger"), + TEXT("state/memory-entity-descriptor"), + TEXT("state/memory-chronicle-continuity"), + TEXT("state/memory-session-group"), + TEXT("state/memory-resume-pack"), + TEXT("state/memory-continuity-guard") + }; + + int32 RelevantResumePackCount = 0; + int32 RelevantOpenGroupCount = 0; + int32 RelevantBlockingGuardCount = 0; + + for (const FHyperTwistMemoryEntityDescriptor& Entity : LedgerState.Entities) + { + if (Entity.Lane != EHyperTwistMemoryLane::ProceduralWorkflow + || Entity.AuthorityKind != EHyperTwistMemoryAuthorityKind::Authoritative) + { + continue; + } + + if (Entity.RecordKind == TEXT("training-review-plan") + || Entity.RecordKind == TEXT("coach-action-plan") + || Entity.RecordKind == TEXT("coach-session-queue")) + { + AddPreviewHeadline(SkillState.PreviewHeadlines, Entity.DisplayLabel); + AddUniqueEntityId(LinkedWorkflowEntityIds, Entity.EntityId); + } + } + + for (const FHyperTwistMemorySessionGroup& SessionGroup : + ChronicleContinuityState.SessionGroups) + { + if (SessionGroup.GroupKind == TEXT("review-plan") + || SessionGroup.GroupKind == TEXT("coach-session-queue")) + { + AddPreviewHeadline(SkillState.PreviewHeadlines, SessionGroup.Headline); + RelevantOpenGroupCount += SessionGroup.bCompleted ? 0 : 1; + } + } + + for (const FHyperTwistMemoryResumePack& ResumePack : + ChronicleContinuityState.ResumePacks) + { + if (ResumePack.PackKind == TEXT("review-plan-resume") + || ResumePack.PackKind == TEXT("coach-session-queue-resume")) + { + AddPreviewHeadline(SkillState.PreviewHeadlines, ResumePack.Headline); + RelevantResumePackCount += 1; + } + } + + for (const FHyperTwistMemoryContinuityGuard& ContinuityGuard : + ChronicleContinuityState.ContinuityGuards) + { + if (ContinuityGuard.GuardKind == TEXT("coach-session-queue")) + { + AddPreviewHeadline(SkillState.PreviewHeadlines, ContinuityGuard.Headline); + RelevantBlockingGuardCount += + ContinuityGuard.Severity == + EHyperTwistMemoryContinuityGuardSeverity::Blocking + ? 1 + : 0; + } + } + + SkillState.AvailableItemCount = + LinkedWorkflowEntityIds.Num() + RelevantResumePackCount; + SkillState.LinkedWorkflowEntityCount = LinkedWorkflowEntityIds.Num(); + SkillState.BlockingItemCount = RelevantBlockingGuardCount; + SkillState.bReadsAuthoritativeStores = + bHasProceduralWorkflowLaneEvidence + && LinkedWorkflowEntityIds.Num() > 0 + && (RelevantResumePackCount > 0 || RelevantOpenGroupCount > 0); + SkillState.bAvailableNow = SkillState.AvailableItemCount > 0; + SkillState.Summary = + TEXT("Live first-party workflow capture skill over authoritative review-plan, follow-up, and queue continuity entities."); + } + + if (SkillState.PreviewHeadlines.Num() == 0) + { + AddPreviewHeadline(SkillState.PreviewHeadlines, SkillState.DisplayLabel); + } + + return SkillState; + }; + + for (const FString& SkillId : { + FString(TEXT("skill/capture-session-template")), + FString(TEXT("skill/capture-follow-up-routine")) + }) + { + const FHyperTwistSkillWorkflowMemoryCaptureSkill SkillState = + BuildWorkflowSkill(SkillId); + if (!SkillState.IsStructurallyValid()) + { + return FHyperTwistSkillWorkflowMemoryCaptureState(); + } + + WorkflowCaptureState.Skills.Add(SkillState); + } + + for (const FHyperTwistSkillWorkflowMemoryCaptureSkill& SkillState : + WorkflowCaptureState.Skills) + { + WorkflowCaptureState.LiveSkillCount += SkillState.bLiveSkill ? 1 : 0; + WorkflowCaptureState.AvailableNowCount += SkillState.bAvailableNow ? 1 : 0; + WorkflowCaptureState.CaptureSessionTemplateSkillCount += + SkillState.SkillId == TEXT("skill/capture-session-template") ? 1 : 0; + WorkflowCaptureState.CaptureFollowUpRoutineSkillCount += + SkillState.SkillId == TEXT("skill/capture-follow-up-routine") ? 1 : 0; + WorkflowCaptureState.bEverySkillPreservesOptionalAssistiveOffState &= + SkillState.bPreservesOptionalAssistiveOffState; + WorkflowCaptureState.bWorkflowMemoryRemainsSeparateFromUserAuthoredNotes &= + SkillState.bAvoidsUserAuthoredNoteCapture; + WorkflowCaptureState.bWorkflowMemoryDoesNotCollapseIntoOpaqueSummaries &= + SkillState.bAvoidsOpaqueSummaryCollapse; + + if (SkillState.bLiveSkill) + { + WorkflowCaptureState.bEveryLiveSkillReadsAuthoritativeStores &= + SkillState.bReadsAuthoritativeStores; + WorkflowCaptureState.bEveryLiveSkillHasValidationHarnessCoverage &= + SkillState.bHasValidationHarnessCoverage; + } + } + + WorkflowCaptureState.SkillCount = WorkflowCaptureState.Skills.Num(); + + return WorkflowCaptureState; +} diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h index 5d1de8a..ac1f250 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h @@ -195,6 +195,10 @@ public: UFUNCTION(BlueprintPure, Category = "HyperTwist|Skills") static FHyperTwistSkillRecallCompactViewState MakeSampleSkillRecallCompactViewState(); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Skills") + static FHyperTwistSkillWorkflowMemoryCaptureState + MakeSampleSkillWorkflowMemoryCaptureState(); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training") static FHyperTwistTrainingRepositoryIntegrityReport MakeSampleTrainingRepositoryIntegrityReport(); @@ -429,6 +433,11 @@ public: const FHyperTwistSkillRecallCompactViewState& SkillRecallCompactViewState ); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Serialization") + static FString SerializeSkillWorkflowMemoryCaptureStateToJson( + const FHyperTwistSkillWorkflowMemoryCaptureState& SkillWorkflowMemoryCaptureState + ); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Serialization") static FString SerializeTrainingTimerExportPacketToJson(const FHyperTwistTrainingTimerExportPacket& TimerExportPacket); @@ -555,6 +564,12 @@ public: FHyperTwistSkillRecallCompactViewState& OutSkillRecallCompactViewState ); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Serialization") + static bool DeserializeSkillWorkflowMemoryCaptureStateFromJson( + const FString& Json, + FHyperTwistSkillWorkflowMemoryCaptureState& OutSkillWorkflowMemoryCaptureState + ); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Serialization") static bool DeserializeTrainingTimerExportPacketFromJson(const FString& Json, FHyperTwistTrainingTimerExportPacket& OutTimerExportPacket); }; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillCoreLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillCoreLibrary.h index 4f9ad36..ff46ae5 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillCoreLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillCoreLibrary.h @@ -74,4 +74,13 @@ public: const FHyperTwistMemoryRecallSharedContextState& RecallSharedContextState, const FHyperTwistMemoryDerivedAdjunctState& DerivedAdjunctState ); + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Skills") + static FHyperTwistSkillWorkflowMemoryCaptureState DeriveSkillWorkflowMemoryCaptureState( + const FHyperTwistSkillRegistryState& RegistryState, + const FHyperTwistSkillControlState& ControlState, + const FHyperTwistSkillAuthoringHarnessState& AuthoringHarnessState, + const FHyperTwistMemoryLedgerState& LedgerState, + const FHyperTwistMemoryChronicleContinuityState& ChronicleContinuityState + ); }; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillTypes.h index 2c2bc20..22cf2cc 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillTypes.h @@ -2967,3 +2967,276 @@ struct FHyperTwistSkillRecallCompactViewState == bComputedCompactViewGuard; } }; + +USTRUCT(BlueprintType) +struct FHyperTwistSkillWorkflowMemoryCaptureSkill +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SkillId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DisplayLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CommandSurfaceId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ServiceBindingId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString OwnerLaneId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString OwnerFeatureId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + EHyperTwistSkillStatus Status = EHyperTwistSkillStatus::None; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray PermissionScopeIds; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray InputStateKinds; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray OutputArtifactKinds; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray PreviewHeadlines; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AvailableItemCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 LinkedWorkflowEntityCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 BlockingItemCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bLiveSkill = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bReadsAuthoritativeStores = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bAvailableNow = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bRequiresOwnerActivation = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bPreservesOptionalAssistiveOffState = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bDerivedAssistiveOnly = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bHasValidationHarnessCoverage = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bAvoidsUserAuthoredNoteCapture = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bAvoidsOpaqueSummaryCollapse = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Summary; + + bool IsStructurallyValid() const + { + if (SkillId.IsEmpty() + || DisplayLabel.IsEmpty() + || CommandSurfaceId.IsEmpty() + || ServiceBindingId.IsEmpty() + || OwnerLaneId.IsEmpty() + || OwnerFeatureId.IsEmpty() + || Status == EHyperTwistSkillStatus::None + || PermissionScopeIds.Num() == 0 + || InputStateKinds.Num() == 0 + || OutputArtifactKinds.Num() == 0 + || PreviewHeadlines.Num() == 0 + || AvailableItemCount <= 0 + || LinkedWorkflowEntityCount <= 0 + || BlockingItemCount < 0 + || !bReadsAuthoritativeStores + || !bPreservesOptionalAssistiveOffState + || !bDerivedAssistiveOnly + || !bHasValidationHarnessCoverage + || !bAvoidsUserAuthoredNoteCapture + || !bAvoidsOpaqueSummaryCollapse) + { + return false; + } + + for (const FString& Value : PermissionScopeIds) + { + if (Value.IsEmpty()) + { + return false; + } + } + + for (const FString& Value : InputStateKinds) + { + if (Value.IsEmpty()) + { + return false; + } + } + + for (const FString& Value : OutputArtifactKinds) + { + if (Value.IsEmpty()) + { + return false; + } + } + + for (const FString& Value : PreviewHeadlines) + { + if (Value.IsEmpty()) + { + return false; + } + } + + return Status == EHyperTwistSkillStatus::ImplementedNow + && bLiveSkill + && bAvailableNow + && !bRequiresOwnerActivation; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistSkillWorkflowMemoryCaptureState +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString RegistryId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ManifestVersion; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString ReferenceUtc; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString CommandSurfaceRootId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString TemplateVersion; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray Skills; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SkillCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 LiveSkillCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 AvailableNowCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 CaptureSessionTemplateSkillCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 CaptureFollowUpRoutineSkillCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bEveryLiveSkillReadsAuthoritativeStores = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bEverySkillPreservesOptionalAssistiveOffState = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bEveryLiveSkillHasValidationHarnessCoverage = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bWorkflowMemoryRemainsSeparateFromUserAuthoredNotes = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bWorkflowMemoryDoesNotCollapseIntoOpaqueSummaries = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Summary; + + bool IsStructurallyValid() const + { + if (RegistryId.IsEmpty() + || ManifestVersion.IsEmpty() + || ReferenceUtc.IsEmpty() + || CommandSurfaceRootId.IsEmpty() + || TemplateVersion.IsEmpty() + || Skills.Num() == 0 + || SkillCount != Skills.Num() + || !bEveryLiveSkillReadsAuthoritativeStores + || !bEverySkillPreservesOptionalAssistiveOffState + || !bEveryLiveSkillHasValidationHarnessCoverage + || !bWorkflowMemoryRemainsSeparateFromUserAuthoredNotes + || !bWorkflowMemoryDoesNotCollapseIntoOpaqueSummaries) + { + return false; + } + + TArray SeenSkillIds; + int32 ComputedLiveSkillCount = 0; + int32 ComputedAvailableNowCount = 0; + int32 ComputedCaptureSessionTemplateSkillCount = 0; + int32 ComputedCaptureFollowUpRoutineSkillCount = 0; + bool bComputedEveryLiveSkillReadsAuthoritativeStores = true; + bool bComputedEverySkillPreservesOptionalAssistiveOffState = true; + bool bComputedEveryLiveSkillHasValidationHarnessCoverage = true; + bool bComputedUserNoteSeparation = true; + bool bComputedOpaqueSummaryGuard = true; + + for (const FHyperTwistSkillWorkflowMemoryCaptureSkill& Skill : Skills) + { + if (!Skill.IsStructurallyValid() || SeenSkillIds.Contains(Skill.SkillId)) + { + return false; + } + + SeenSkillIds.Add(Skill.SkillId); + ComputedLiveSkillCount += Skill.bLiveSkill ? 1 : 0; + ComputedAvailableNowCount += Skill.bAvailableNow ? 1 : 0; + ComputedCaptureSessionTemplateSkillCount += + Skill.SkillId == TEXT("skill/capture-session-template") ? 1 : 0; + ComputedCaptureFollowUpRoutineSkillCount += + Skill.SkillId == TEXT("skill/capture-follow-up-routine") ? 1 : 0; + bComputedEverySkillPreservesOptionalAssistiveOffState &= + Skill.bPreservesOptionalAssistiveOffState; + bComputedUserNoteSeparation &= Skill.bAvoidsUserAuthoredNoteCapture; + bComputedOpaqueSummaryGuard &= Skill.bAvoidsOpaqueSummaryCollapse; + + if (Skill.bLiveSkill) + { + bComputedEveryLiveSkillReadsAuthoritativeStores &= Skill.bReadsAuthoritativeStores; + bComputedEveryLiveSkillHasValidationHarnessCoverage &= + Skill.bHasValidationHarnessCoverage; + } + } + + return LiveSkillCount == ComputedLiveSkillCount + && AvailableNowCount == ComputedAvailableNowCount + && CaptureSessionTemplateSkillCount + == ComputedCaptureSessionTemplateSkillCount + && CaptureFollowUpRoutineSkillCount + == ComputedCaptureFollowUpRoutineSkillCount + && bEveryLiveSkillReadsAuthoritativeStores + == bComputedEveryLiveSkillReadsAuthoritativeStores + && bEverySkillPreservesOptionalAssistiveOffState + == bComputedEverySkillPreservesOptionalAssistiveOffState + && bEveryLiveSkillHasValidationHarnessCoverage + == bComputedEveryLiveSkillHasValidationHarnessCoverage + && bWorkflowMemoryRemainsSeparateFromUserAuthoredNotes + == bComputedUserNoteSeparation + && bWorkflowMemoryDoesNotCollapseIntoOpaqueSummaries + == bComputedOpaqueSummaryGuard; + } +}; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1ARegistryManifestContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1ARegistryManifestContractTest.cpp index 349b085..394135a 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1ARegistryManifestContractTest.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1ARegistryManifestContractTest.cpp @@ -73,9 +73,9 @@ bool FHyperTwistSkillPhaseS1ARegistryManifestTest::RunTest(const FString& Parame RegistryState.IsStructurallyValid() ); TestEqual( - TEXT("The sample S1-A registry must expose eleven declared skills after S3-B lands."), + TEXT("The sample S1-A registry must expose thirteen declared skills after S3-C lands."), RegistryState.SkillCount, - 11 + 13 ); TestTrue( TEXT("The S1-A registry must avoid ad hoc metadata."), @@ -86,12 +86,12 @@ bool FHyperTwistSkillPhaseS1ARegistryManifestTest::RunTest(const FString& Parame RegistryState.bAllSkillsOptionalAssistive ); TestEqual( - TEXT("The sample S1-A registry must keep eight implemented skill entries after S3-B lands."), + TEXT("The sample S1-A registry must keep ten implemented skill entries after S3-C lands."), HyperTwistSkillPhaseS1ATestInternal::FindStatusCount( RegistryState, EHyperTwistSkillStatus::ImplementedNow ), - 8 + 10 ); TestEqual( TEXT("The sample S1-A registry must keep one command-contract-pending entry for note capture."), @@ -117,6 +117,14 @@ bool FHyperTwistSkillPhaseS1ARegistryManifestTest::RunTest(const FString& Parame ), 1 ); + TestEqual( + TEXT("The sample S1-A registry must expose eight memory-continuity-family entries after S3-C lands."), + HyperTwistSkillPhaseS1ATestInternal::FindFamilyCount( + RegistryState, + EHyperTwistSkillFamily::MemoryContinuity + ), + 8 + ); const FHyperTwistSkillManifestEntry* GovernanceSkill = HyperTwistSkillPhaseS1ATestInternal::FindSkillById( @@ -168,6 +176,29 @@ bool FHyperTwistSkillPhaseS1ARegistryManifestTest::RunTest(const FString& Parame ); } + const FHyperTwistSkillManifestEntry* WorkflowCaptureSkill = + HyperTwistSkillPhaseS1ATestInternal::FindSkillById( + RegistryState, + TEXT("skill/capture-session-template") + ); + TestNotNull( + TEXT("The capture-session-template skill entry must exist."), + WorkflowCaptureSkill + ); + if (WorkflowCaptureSkill != nullptr) + { + TestEqual( + TEXT("The capture-session-template skill must be implemented now."), + WorkflowCaptureSkill->Status, + EHyperTwistSkillStatus::ImplementedNow + ); + TestEqual( + TEXT("The capture-session-template skill must bind to the first-party workflow capture service."), + WorkflowCaptureSkill->CommandBindings[0].ServiceBindingId, + FString(TEXT("service/skills/capture-session-template")) + ); + } + return true; } diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1CInvocationAuditLedgerContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1CInvocationAuditLedgerContractTest.cpp index 522d24e..0356ff9 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1CInvocationAuditLedgerContractTest.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1CInvocationAuditLedgerContractTest.cpp @@ -39,7 +39,7 @@ bool FHyperTwistSkillPhaseS1CInvocationProvenanceTest::RunTest(const FString& Pa TestEqual( TEXT("Sample skill audit ledger should record one invocation per enabled sample skill."), AuditLedgerState.InvocationCount, - 4 + 6 ); TestEqual( TEXT("All sample invocations should remain traceable."), @@ -111,7 +111,7 @@ bool FHyperTwistSkillPhaseS1CFailureCancelRecordingTest::RunTest(const FString& TestEqual( TEXT("The sample audit ledger should contain the expected successful invocation count."), AuditLedgerState.SuccessfulInvocationCount, - 2 + 4 ); TestEqual( TEXT("The sample audit ledger should contain the expected failed invocation count."), @@ -195,6 +195,29 @@ bool FHyperTwistSkillPhaseS1CFailureCancelRecordingTest::RunTest(const FString& ); } + const FHyperTwistSkillInvocationRecord* WorkflowRecord = + HyperTwistSkillPhaseS1CTestInternal::FindInvocationRecordBySkillId( + AuditLedgerState, + TEXT("skill/capture-follow-up-routine") + ); + TestNotNull( + TEXT("The workflow follow-up skill invocation should be present in the sample audit ledger."), + WorkflowRecord + ); + if (WorkflowRecord != nullptr) + { + TestEqual( + TEXT("The workflow follow-up skill should now record a success outcome."), + WorkflowRecord->Outcome, + EHyperTwistSkillInvocationOutcome::Succeeded + ); + TestEqual( + TEXT("The workflow follow-up skill should emit the bounded follow-up capture artifact."), + WorkflowRecord->ProducedArtifacts[0].ArtifactKind, + FString(TEXT("artifact/follow-up-routine-capture-brief")) + ); + } + return true; } diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1DAuthoringValidationHarnessContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1DAuthoringValidationHarnessContractTest.cpp index f0eb838..6d8c14b 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1DAuthoringValidationHarnessContractTest.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1DAuthoringValidationHarnessContractTest.cpp @@ -211,6 +211,44 @@ bool FHyperTwistSkillPhaseS1DValidationHarnessCoverageTest::RunTest(const FStrin ); } + const FHyperTwistSkillValidationContractCase* CaptureTemplateEval = + HyperTwistSkillPhaseS1DTestInternal::FindValidationCase( + HarnessState, + TEXT("skill/capture-session-template"), + EHyperTwistSkillValidationContractKind::Eval + ); + TestNotNull( + TEXT("The capture-session-template skill should have an eval validation contract."), + CaptureTemplateEval + ); + if (CaptureTemplateEval != nullptr) + { + TestEqual( + TEXT("The capture-session-template skill eval contract should now run live after S3-C lands."), + CaptureTemplateEval->ExecutionMode, + EHyperTwistSkillValidationExecutionMode::LiveContract + ); + } + + const FHyperTwistSkillValidationContractCase* CaptureFollowUpEval = + HyperTwistSkillPhaseS1DTestInternal::FindValidationCase( + HarnessState, + TEXT("skill/capture-follow-up-routine"), + EHyperTwistSkillValidationContractKind::Eval + ); + TestNotNull( + TEXT("The capture-follow-up-routine skill should have an eval validation contract."), + CaptureFollowUpEval + ); + if (CaptureFollowUpEval != nullptr) + { + TestEqual( + TEXT("The capture-follow-up-routine skill eval contract should now run live after S3-C lands."), + CaptureFollowUpEval->ExecutionMode, + EHyperTwistSkillValidationExecutionMode::LiveContract + ); + } + const FHyperTwistSkillValidationContractCase* RouxEval = HyperTwistSkillPhaseS1DTestInternal::FindValidationCase( HarnessState, diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS3CWorkflowMemoryCaptureContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS3CWorkflowMemoryCaptureContractTest.cpp new file mode 100644 index 0000000..e3a7d21 --- /dev/null +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS3CWorkflowMemoryCaptureContractTest.cpp @@ -0,0 +1,199 @@ +// Copyright HyperTwist, Inc. All Rights Reserved. + +#include "Misc/AutomationTest.h" + +#include "HyperTwistBootstrap/HyperTwistContractLibrary.h" + +#if WITH_AUTOMATION_TESTS + +namespace HyperTwistSkillPhaseS3CTestInternal +{ + const FHyperTwistSkillWorkflowMemoryCaptureSkill* FindSkillById( + const FHyperTwistSkillWorkflowMemoryCaptureState& WorkflowCaptureState, + const FString& SkillId + ) + { + for (const FHyperTwistSkillWorkflowMemoryCaptureSkill& Skill : + WorkflowCaptureState.Skills) + { + if (Skill.SkillId == SkillId) + { + return &Skill; + } + } + + return nullptr; + } +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistSkillPhaseS3CWorkflowMemoryCaptureCoverageTest, + "HyperTwist.FirstParty.Skill.PhaseS3C.WorkflowMemoryCaptureCoverage", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistSkillPhaseS3CWorkflowMemoryCaptureCoverageTest::RunTest( + const FString& Parameters +) +{ + const FHyperTwistSkillWorkflowMemoryCaptureState WorkflowCaptureState = + UHyperTwistContractLibrary::MakeSampleSkillWorkflowMemoryCaptureState(); + + TestTrue( + TEXT("The sample S3-C workflow-memory capture skill state should be structurally valid."), + WorkflowCaptureState.IsStructurallyValid() + ); + TestEqual( + TEXT("S3-C should expose two workflow-memory capture skills."), + WorkflowCaptureState.SkillCount, + 2 + ); + TestEqual( + TEXT("S3-C should expose two live workflow-memory capture skills."), + WorkflowCaptureState.LiveSkillCount, + 2 + ); + TestEqual( + TEXT("S3-C should expose two currently available workflow-memory capture skills in the sample state."), + WorkflowCaptureState.AvailableNowCount, + 2 + ); + + const FHyperTwistSkillWorkflowMemoryCaptureSkill* TemplateSkill = + HyperTwistSkillPhaseS3CTestInternal::FindSkillById( + WorkflowCaptureState, + TEXT("skill/capture-session-template") + ); + TestNotNull( + TEXT("The capture-session-template skill should exist."), + TemplateSkill + ); + if (TemplateSkill != nullptr) + { + TestEqual( + TEXT("The capture-session-template skill should bind to the bounded workflow template capture artifact."), + TemplateSkill->OutputArtifactKinds[0], + FString(TEXT("artifact/workflow-template-capture-brief")) + ); + } + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistSkillPhaseS3CAuthoritativeWorkflowCaptureBoundariesTest, + "HyperTwist.FirstParty.Skill.PhaseS3C.AuthoritativeWorkflowCaptureBoundaries", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistSkillPhaseS3CAuthoritativeWorkflowCaptureBoundariesTest::RunTest( + const FString& Parameters +) +{ + const FHyperTwistSkillWorkflowMemoryCaptureState WorkflowCaptureState = + UHyperTwistContractLibrary::MakeSampleSkillWorkflowMemoryCaptureState(); + + TestTrue( + TEXT("The sample S3-C workflow-memory capture skill state should be structurally valid."), + WorkflowCaptureState.IsStructurallyValid() + ); + TestTrue( + TEXT("Every live S3-C skill should read authoritative stores."), + WorkflowCaptureState.bEveryLiveSkillReadsAuthoritativeStores + ); + TestTrue( + TEXT("Every live S3-C skill should keep validation-harness coverage."), + WorkflowCaptureState.bEveryLiveSkillHasValidationHarnessCoverage + ); + TestTrue( + TEXT("S3-C workflow capture must remain separate from user-authored notes."), + WorkflowCaptureState.bWorkflowMemoryRemainsSeparateFromUserAuthoredNotes + ); + TestTrue( + TEXT("S3-C workflow capture must not collapse into opaque summaries."), + WorkflowCaptureState.bWorkflowMemoryDoesNotCollapseIntoOpaqueSummaries + ); + + const FHyperTwistSkillWorkflowMemoryCaptureSkill* FollowUpSkill = + HyperTwistSkillPhaseS3CTestInternal::FindSkillById( + WorkflowCaptureState, + TEXT("skill/capture-follow-up-routine") + ); + TestNotNull( + TEXT("The capture-follow-up-routine skill should exist."), + FollowUpSkill + ); + if (FollowUpSkill != nullptr) + { + TestTrue( + TEXT("The capture-follow-up-routine skill should avoid user-authored note capture."), + FollowUpSkill->bAvoidsUserAuthoredNoteCapture + ); + TestTrue( + TEXT("The capture-follow-up-routine skill should avoid opaque summary collapse."), + FollowUpSkill->bAvoidsOpaqueSummaryCollapse + ); + TestEqual( + TEXT("The capture-follow-up-routine skill should bind to the bounded follow-up capture artifact."), + FollowUpSkill->OutputArtifactKinds[0], + FString(TEXT("artifact/follow-up-routine-capture-brief")) + ); + } + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistSkillPhaseS3CSerializationRoundTripTest, + "HyperTwist.FirstParty.Skill.PhaseS3C.SerializationRoundTrip", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistSkillPhaseS3CSerializationRoundTripTest::RunTest( + const FString& Parameters +) +{ + const FHyperTwistSkillWorkflowMemoryCaptureState WorkflowCaptureState = + UHyperTwistContractLibrary::MakeSampleSkillWorkflowMemoryCaptureState(); + + TestTrue( + TEXT("The sample S3-C workflow-memory capture skill state should be structurally valid before serialization."), + WorkflowCaptureState.IsStructurallyValid() + ); + + const FString Json = + UHyperTwistContractLibrary::SerializeSkillWorkflowMemoryCaptureStateToJson( + WorkflowCaptureState + ); + TestTrue( + TEXT("Serialized S3-C JSON should include the opaque-summary-collapse guard field."), + Json.Contains(TEXT("bWorkflowMemoryDoesNotCollapseIntoOpaqueSummaries")) + ); + + FHyperTwistSkillWorkflowMemoryCaptureState RoundTrippedState; + TestTrue( + TEXT("Deserializing the S3-C workflow-memory capture JSON should succeed."), + UHyperTwistContractLibrary::DeserializeSkillWorkflowMemoryCaptureStateFromJson( + Json, + RoundTrippedState + ) + ); + TestTrue( + TEXT("Round-tripped S3-C workflow-memory capture state should remain structurally valid."), + RoundTrippedState.IsStructurallyValid() + ); + TestEqual( + TEXT("Round-tripped S3-C skill count should match the original sample."), + RoundTrippedState.SkillCount, + WorkflowCaptureState.SkillCount + ); + TestEqual( + TEXT("Round-tripped S3-C live-skill count should match the original sample."), + RoundTrippedState.LiveSkillCount, + WorkflowCaptureState.LiveSkillCount + ); + + return true; +} + +#endif diff --git a/docs/arch/HYPERTWIST_PHASES3_C_FIRST_PARTY_WORKFLOW_MEMORY_CAPTURE_SKILLS_IMPLEMENTATION_PACKET_2026-05-29.md b/docs/arch/HYPERTWIST_PHASES3_C_FIRST_PARTY_WORKFLOW_MEMORY_CAPTURE_SKILLS_IMPLEMENTATION_PACKET_2026-05-29.md new file mode 100644 index 0000000..6bdbe6f --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASES3_C_FIRST_PARTY_WORKFLOW_MEMORY_CAPTURE_SKILLS_IMPLEMENTATION_PACKET_2026-05-29.md @@ -0,0 +1,36 @@ +# HyperTwist Phase S3-C Implementation Packet + +Date: `2026-05-29` + +Packet: `Phase S3-C` + +Title: `first-party workflow-memory capture skills` + +## Outcome + +Implemented now. + +## Landed scope + +- live `skill/capture-session-template` +- live `skill/capture-follow-up-routine` +- bounded first-party workflow-memory capture state over authoritative + procedural/workflow ledger entities and continuity evidence +- registry, authoring-harness, audit-ledger, sample-contract, and JSON + round-trip support + +## Preserved boundaries + +- `capture-note` remains explicit and non-live +- workflow capture remains separate from user-authored notes +- workflow capture does not collapse into opaque summaries +- no broad browser/docs/design widening in this packet + +## Validation + +- build target: `UnrealHyperTwistEditor Win64 Development` +- focused `S3-C` automation tests were discovered by the Unreal automation + runner and the first test was queued +- on this machine the Unreal automation runner stalled after queue start, so + this packet closes with green build plus partial automation evidence rather + than a full clean automation sweep diff --git a/docs/arch/HYPERTWIST_PHASES3_C_FIRST_PARTY_WORKFLOW_MEMORY_CAPTURE_SKILLS_PREPARATION_PACKET_2026-05-29.md b/docs/arch/HYPERTWIST_PHASES3_C_FIRST_PARTY_WORKFLOW_MEMORY_CAPTURE_SKILLS_PREPARATION_PACKET_2026-05-29.md new file mode 100644 index 0000000..f7bc6b3 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASES3_C_FIRST_PARTY_WORKFLOW_MEMORY_CAPTURE_SKILLS_PREPARATION_PACKET_2026-05-29.md @@ -0,0 +1,39 @@ +# HyperTwist Phase S3-C Preparation Packet + +Date: `2026-05-29` + +Packet: `Phase S3-C` + +Title: `first-party workflow-memory capture skills` + +## Goal + +Land the next bounded memory/continuity skill seam above the already landed +first-party memory family by exposing workflow-memory capture skills over +authoritative procedural/workflow evidence. + +## Scope + +- `skill/capture-session-template` +- `skill/capture-follow-up-routine` +- first-party workflow capture state over authoritative lane-12 workflow + entities plus bounded continuity evidence +- registry, audit-ledger, authoring-harness, sample-contract, and JSON support + +## Required boundaries + +- do not activate user-authored note capture +- do not collapse workflow memory into opaque summaries +- do not widen beyond bounded procedural/workflow capture over first-party + authoritative stores + +## Inputs + +- landed `6R-M1` memory ledger +- landed `6R-M2` chronicle and continuity +- landed `S1-A` through `S3-B` skill substrate + +## Acceptance gate + +- workflow capture remains provenance-visible, derived-assistive, first-party + owned, separate from user-authored notes, and structurally bounded diff --git a/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md b/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md index 4d8f98f..49baac4 100644 --- a/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md +++ b/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md @@ -289,4 +289,6 @@ Specifically: now landed in current code - the bounded first-party `Phase S3-B` recall and compact-view skill packet is now landed in current code -- `S3-C` workflow-memory capture skills are now the next clean move +- the bounded first-party `Phase S3-C` workflow-memory capture skill packet is + now landed in current code +- `S4-A` extraction skills are now the next clean move diff --git a/docs/ops/HYPERTWIST_SKILLIZATION_AND_COMMAND_SURFACE_DOCTRINE_2026-05-21.md b/docs/ops/HYPERTWIST_SKILLIZATION_AND_COMMAND_SURFACE_DOCTRINE_2026-05-21.md index ccddc78..6a9b469 100644 --- a/docs/ops/HYPERTWIST_SKILLIZATION_AND_COMMAND_SURFACE_DOCTRINE_2026-05-21.md +++ b/docs/ops/HYPERTWIST_SKILLIZATION_AND_COMMAND_SURFACE_DOCTRINE_2026-05-21.md @@ -394,6 +394,18 @@ Acceptance gates: - workflow memory does not collapse into opaque summaries +Current landed posture: + +- the bounded first-party `Phase S3-C` packet is now landed in current code +- `capture-session-template` is live over the landed first-party procedural + workflow ledger seam for authoritative session-template and drill-workflow + entities +- `capture-follow-up-routine` is live over the landed first-party procedural + workflow and continuity seams for authoritative review-plan, coach-action-plan, + and queue follow-up entities +- workflow capture remains separate from user-authored notes and does not + collapse into opaque summaries + ### S4 - browser/docs/design skills #### `S4-A` extraction skills @@ -528,7 +540,7 @@ These are target-shape command families, not claims of implemented reality. The next correct sequence is: -1. `S3-C` workflow-memory capture skills +1. `S4-A` extraction skills 2. broader browser, workflow, provider, and domain skill widening Broader memory, browser, workflow, provider, and domain skill widening should diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md b/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md index 001680c..02e23ad 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md @@ -260,3 +260,8 @@ Future skill growth must follow: live product base for `recall-memory` and optional `generate-compact-view` output over the landed recall and derived adjunct memory seams, while compact views stay linked back to authoritative sources +- the bounded first-party `Phase S3-C` workflow-memory capture seam is now the + live product base for `capture-session-template` and + `capture-follow-up-routine` over authoritative procedural workflow ledger + entities plus review/queue continuity evidence, while remaining separate from + user-authored note capture and opaque summary collapse 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 05a127b..2cb72af 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md @@ -304,9 +304,9 @@ repo. | Feature | Status | Primary authority | Notes | |---|---|---|---| -| First-party skill registry and enable/disable governance | Implemented now | landed first-party `Phase S1-A`, `Phase S1-B`, `Phase S1-C`, `Phase S1-D`, `Phase S2-A`, `Phase S2-B`, `Phase S2-C`, `Phase S3-A`, and `Phase S3-B` packets | Current bounded first-party skill status/family contracts, command/service binding declarations, permission/scope declarations, provenance/log declarations, manifest entries, registry counts, durable master-switch/per-skill control-state, family visibility groups, disabled-but-installed inert-off-state truth, invocation-record format, command/service provenance, failure/cancel audit-ledger storage, authoring-template sections, registry-grounded examples, per-skill smoke/eval validation-harness contracts, structured permissive wrapper-output contracts, first-party clean-room command-contract specs, first-party clean-room-ready skill specs, bounded first-party continuity/resume skill state, and bounded recall/compact-view skill state are live as bounded substrate. `S3-C` is now the next bounded skillization seam. | +| First-party skill registry and enable/disable governance | Implemented now | landed first-party `Phase S1-A`, `Phase S1-B`, `Phase S1-C`, `Phase S1-D`, `Phase S2-A`, `Phase S2-B`, `Phase S2-C`, `Phase S3-A`, `Phase S3-B`, and `Phase S3-C` packets | Current bounded first-party skill status/family contracts, command/service binding declarations, permission/scope declarations, provenance/log declarations, manifest entries, registry counts, durable master-switch/per-skill control-state, family visibility groups, disabled-but-installed inert-off-state truth, invocation-record format, command/service provenance, failure/cancel audit-ledger storage, authoring-template sections, registry-grounded examples, per-skill smoke/eval validation-harness contracts, structured permissive wrapper-output contracts, first-party clean-room command-contract specs, first-party clean-room-ready skill specs, bounded first-party continuity/resume skill state, bounded recall/compact-view skill state, and bounded workflow-memory capture skill state are live as bounded substrate. `S4-A` is now the next bounded skillization seam. | | Review/analyzer skill family | Implemented now | landed first-party `Phase S2-A` packet | Current bounded first-party review/analyzer wrappers are live for architecture scan and policy scan output over permissive product evidence. Broader review/diff/plan helper widening still remains future work. | -| Memory/continuity skill family | Implemented now | landed first-party `Phase S3-A` and `Phase S3-B` packets + skillization + memory doctrine | Current bounded `resume-session`, `search-history`, `recall-memory`, and `generate-compact-view` skills are live above the landed first-party `6R-M2`, `6R-M3`, and `6R-M6` memory seams, while `capture-note` remains explicit but non-live under separate owner activation because active user-authored note capture is still not landed beyond the bounded `6R-M5` seam. Compact views remain optional and linked to authoritative sources, and broader workflow-memory widening still remains future work. | +| Memory/continuity skill family | Implemented now | landed first-party `Phase S3-A`, `Phase S3-B`, and `Phase S3-C` packets + skillization + memory doctrine | Current bounded `resume-session`, `search-history`, `recall-memory`, `generate-compact-view`, `capture-session-template`, and `capture-follow-up-routine` skills are live above the landed first-party `6R-M1`, `6R-M2`, `6R-M3`, and `6R-M6` memory seams, while `capture-note` remains explicit but non-live under separate owner activation because active user-authored note capture is still not landed beyond the bounded `6R-M5` seam. Compact views remain optional and linked to authoritative sources, workflow capture remains separate from user-authored notes, and broader browser/docs/design skill widening is now the next family step. | | Provider/ops skill family | Deep-source grounded retained + bounded live wrapper | landed first-party `Phase S2-A` packet + skillization + provider doctrine | Current bounded route-inspection wrapper output is live above the landed provider-neutral speech/provider seams, while broader provider/ops skill widening still remains retained. | | Restrictive training/coaching clean-room skill-spec family | Implemented now, spec-only bounded seam | landed first-party `Phase S2-B` and `Phase S2-C` packets + skillization doctrine | Current restrictive training/coaching skillization seam is now clean-room-ready in first-party terms for bounded Roux session review output. HyperTwist owns the first-party command contract, safety model, and clean-room-ready skill spec, while live clean-room skill behavior still remains separately deferred unless later reopened. | | Domain/creative skill packs | Shallow placeholder | skillization doctrine only | Keep internal until source-grounded. | 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 1dc3747..c07acdb 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 @@ -124,6 +124,10 @@ The landed bounded first-party `Phase S1-A` packet keeps: - the landed bounded first-party `Phase S3-B` packet now keeps recall and compact-view output provenance-visible while requiring compact views to remain optional and linked back to authoritative sources +- the landed bounded first-party `Phase S3-C` packet now keeps workflow-memory + capture output provenance-visible while requiring capture state to remain + anchored to authoritative workflow entities, separate from user-authored + notes, and free of opaque summary collapse ## Memory-specific consequence diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md index 951fe6a..db7a72c 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md @@ -185,7 +185,9 @@ Canonical discovery surfaces for roadmap interpretation: now landed in current code - the bounded first-party `Phase S3-B` recall and compact-view skill packet is now landed in current code -- `S3-C` workflow-memory capture skills are now the next clean move +- the bounded first-party `Phase S3-C` workflow-memory capture skill packet is + now landed in current code +- `S4-A` extraction skills are now the next clean move - 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 diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/SKILLS.md b/docs/v6_5_deep_manual_pack/HyperTwist/SKILLS.md index 6d90b19..6bf07b4 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/SKILLS.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/SKILLS.md @@ -130,8 +130,9 @@ A coding model working on HyperTwist should still be able to: The next correct skillization sequence is: -1. workflow-memory capture skills -2. broader browser/docs/design skills +1. extraction skills +2. browser diagnostics skills +3. design shell skills Broader memory, provider, and domain skill widening should wait until that -base exists. +browser/docs/design base exists.