From 28b546eb69cc5ea9e3793a9a3d92a803d3cf2370 Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Thu, 28 May 2026 23:58:00 +0200 Subject: [PATCH] Implement Phase S2-A permissive analyzer wrappers --- .../HyperTwistContractLibrary.cpp | 34 ++ .../HyperTwistSkillCoreLibrary.cpp | 297 +++++++++++++++--- .../HyperTwistContractLibrary.h | 14 + .../HyperTwistSkillCoreLibrary.h | 7 + .../HyperTwistSkills/HyperTwistSkillTypes.h | 216 +++++++++++++ ...llPhaseS1ARegistryManifestContractTest.cpp | 36 +-- ...seS1CInvocationAuditLedgerContractTest.cpp | 45 ++- ...AuthoringValidationHarnessContractTest.cpp | 4 +- ...APermissiveAnalyzerWrapperContractTest.cpp | 210 +++++++++++++ ...APPERS_IMPLEMENTATION_PACKET_2026-05-28.md | 100 ++++++ ..._WRAPPERS_PREPARATION_PACKET_2026-05-28.md | 95 ++++++ ...PERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md | 5 +- ...AND_COMMAND_SURFACE_DOCTRINE_2026-05-21.md | 20 +- .../HyperTwist/ARCHITECTURE.md | 3 +- .../HyperTwist/FEATURE_REGISTRY.md | 8 +- .../HyperTwist/PROVENANCE_AND_TRUST_MODEL.md | 6 +- .../HyperTwist/ROADMAP.md | 5 + .../HyperTwist/SKILLS.md | 6 +- 18 files changed, 1023 insertions(+), 88 deletions(-) create mode 100644 UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS2APermissiveAnalyzerWrapperContractTest.cpp create mode 100644 docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_IMPLEMENTATION_PACKET_2026-05-28.md create mode 100644 docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_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 b3e75c1..d2887d2 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistBootstrap/HyperTwistContractLibrary.cpp @@ -4018,6 +4018,20 @@ FHyperTwistSkillAuthoringHarnessState UHyperTwistContractLibrary::MakeSampleSkil ); } +FHyperTwistSkillAnalyzerWrapperState UHyperTwistContractLibrary::MakeSampleSkillAnalyzerWrapperState() +{ + const FHyperTwistSkillRegistryState RegistryState = MakeSampleSkillRegistryState(); + const FHyperTwistSkillControlState ControlState = MakeSampleSkillControlState(); + const FHyperTwistSkillAuthoringHarnessState AuthoringHarnessState = + MakeSampleSkillAuthoringHarnessState(); + + return UHyperTwistSkillCoreLibrary::DeriveSkillAnalyzerWrapperState( + RegistryState, + ControlState, + AuthoringHarnessState + ); +} + FHyperTwistTrainingRepositoryIntegrityReport UHyperTwistContractLibrary::MakeSampleTrainingRepositoryIntegrityReport() { FHyperTwistTrainingRepositoryState RepositoryState = MakeSampleTrainingRepositoryState(); @@ -5163,6 +5177,15 @@ FString UHyperTwistContractLibrary::SerializeSkillAuthoringHarnessStateToJson( ); } +FString UHyperTwistContractLibrary::SerializeSkillAnalyzerWrapperStateToJson( + const FHyperTwistSkillAnalyzerWrapperState& SkillAnalyzerWrapperState +) +{ + return HyperTwistContractLibraryInternal::SerializeStructToJson( + SkillAnalyzerWrapperState + ); +} + FString UHyperTwistContractLibrary::SerializeTrainingTimerExportPacketToJson( const FHyperTwistTrainingTimerExportPacket& TimerExportPacket ) @@ -5329,6 +5352,17 @@ bool UHyperTwistContractLibrary::DeserializeSkillAuthoringHarnessStateFromJson( ); } +bool UHyperTwistContractLibrary::DeserializeSkillAnalyzerWrapperStateFromJson( + const FString& Json, + FHyperTwistSkillAnalyzerWrapperState& OutSkillAnalyzerWrapperState +) +{ + return HyperTwistContractLibraryInternal::DeserializeStructFromJson( + Json, + OutSkillAnalyzerWrapperState + ); +} + 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 b275271..0f992f0 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistSkills/HyperTwistSkillCoreLibrary.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistSkills/HyperTwistSkillCoreLibrary.cpp @@ -325,6 +325,50 @@ namespace HyperTwistSkillCoreLibraryInternal ); } + const FHyperTwistSkillControlStateEntry* FindControlStateEntryById( + const FHyperTwistSkillControlState& ControlState, + const FString& SkillId + ) + { + return ControlState.SkillStates.FindByPredicate( + [&SkillId](const FHyperTwistSkillControlStateEntry& Entry) + { + return Entry.SkillId == SkillId; + } + ); + } + + const FHyperTwistSkillAuthoringExampleState* FindAuthoringExampleBySkillId( + const FHyperTwistSkillAuthoringHarnessState& HarnessState, + const FString& SkillId + ) + { + return HarnessState.Examples.FindByPredicate( + [&SkillId](const FHyperTwistSkillAuthoringExampleState& Entry) + { + return Entry.SkillId == SkillId; + } + ); + } + + bool HasLiveEvalValidationCase( + const FHyperTwistSkillAuthoringHarnessState& HarnessState, + const FString& SkillId + ) + { + const FHyperTwistSkillValidationContractCase* ValidationCase = + HarnessState.ValidationCases.FindByPredicate( + [&SkillId](const FHyperTwistSkillValidationContractCase& Entry) + { + return Entry.SkillId == SkillId + && Entry.Kind == EHyperTwistSkillValidationContractKind::Eval + && Entry.ExecutionMode == EHyperTwistSkillValidationExecutionMode::LiveContract; + } + ); + + return ValidationCase != nullptr && ValidationCase->IsStructurallyValid(); + } + FString MakeInvocationSlug(const FString& SkillId) { FString Slug = MakeSkillSettingsSlug(SkillId); @@ -350,6 +394,92 @@ namespace HyperTwistSkillCoreLibraryInternal return ScopeIds; } + bool IsPermissiveAnalyzerWrapperSkill(const FString& SkillId) + { + return SkillId == TEXT("skill/review-architecture") + || SkillId == TEXT("skill/memory-resume-briefing") + || SkillId == TEXT("skill/provider-routing-inspector"); + } + + FString MakeAnalyzerWrapperOutputKindId(const FString& ArtifactKind) + { + if (ArtifactKind == TEXT("artifact/architecture-scan")) + { + return TEXT("wrapper-output/architecture-scan"); + } + + if (ArtifactKind == TEXT("artifact/policy-scan")) + { + return TEXT("wrapper-output/policy-scan"); + } + + if (ArtifactKind == TEXT("artifact/route-inspection-packet")) + { + return TEXT("wrapper-output/route-inspection"); + } + + if (ArtifactKind == TEXT("artifact/watch-and-recheck-brief")) + { + return TEXT("wrapper-output/watch-and-recheck"); + } + + return FString(); + } + + FString MakeAnalyzerWrapperOutputDisplayLabel( + const FHyperTwistSkillManifestEntry& Entry, + const FString& OutputKindId + ) + { + if (OutputKindId == TEXT("wrapper-output/architecture-scan")) + { + return Entry.DisplayLabel + TEXT(" - Architecture Scan"); + } + + if (OutputKindId == TEXT("wrapper-output/policy-scan")) + { + return Entry.DisplayLabel + TEXT(" - Policy Scan"); + } + + if (OutputKindId == TEXT("wrapper-output/route-inspection")) + { + return Entry.DisplayLabel + TEXT(" - Route Inspection"); + } + + return Entry.DisplayLabel + TEXT(" - Watch And Recheck"); + } + + FHyperTwistSkillAnalyzerWrapperOutput MakeAnalyzerWrapperOutput( + const FHyperTwistSkillManifestEntry& Entry, + const FString& ArtifactKind + ) + { + const FString OutputKindId = MakeAnalyzerWrapperOutputKindId(ArtifactKind); + + FHyperTwistSkillAnalyzerWrapperOutput Output; + Output.WrapperOutputId = + TEXT("wrapper-output/") + + MakeInvocationSlug(Entry.SkillId) + + TEXT("/") + + MakeSkillSettingsSlug(OutputKindId); + Output.SkillId = Entry.SkillId; + Output.DisplayLabel = MakeAnalyzerWrapperOutputDisplayLabel(Entry, OutputKindId); + Output.OutputKindId = OutputKindId; + Output.CommandSurfaceId = Entry.CommandBindings[0].CommandSurfaceId; + Output.ServiceBindingId = Entry.CommandBindings[0].ServiceBindingId; + Output.OwnerLaneId = Entry.OwnerLaneId; + Output.OwnerFeatureId = Entry.OwnerFeatureId; + Output.ArtifactKind = ArtifactKind; + Output.PermissionScopeIds = MakePermissionScopeIds(Entry); + Output.bLiveWrapper = Entry.Status == EHyperTwistSkillStatus::ImplementedNow; + Output.bStableInvocationPattern = true; + Output.bStructuredOutput = true; + Output.bDerivedAssistiveOnly = Entry.bOptionalAssistive; + Output.Summary = + TEXT("Structured first-party permissive wrapper output over a landed HyperTwist seam."); + return Output; + } + FHyperTwistSkillCommandProvenanceState MakeCommandProvenanceState( const FHyperTwistSkillManifestEntry& Entry ) @@ -384,6 +514,11 @@ namespace HyperTwistSkillCoreLibraryInternal return EHyperTwistSkillInvocationOutcome::Succeeded; } + if (Entry.SkillId == TEXT("skill/review-architecture")) + { + return EHyperTwistSkillInvocationOutcome::Succeeded; + } + if (Entry.SkillId == TEXT("skill/memory-resume-briefing")) { return EHyperTwistSkillInvocationOutcome::Cancelled; @@ -409,14 +544,9 @@ namespace HyperTwistSkillCoreLibraryInternal FString MakeInvocationFailureReason(const FHyperTwistSkillManifestEntry& Entry) { - if (Entry.SkillId == TEXT("skill/review-architecture")) - { - return TEXT("Analyzer wrapper remains deferred; invocation was recorded without emitting review output."); - } - if (Entry.SkillId == TEXT("skill/provider-routing-inspector")) { - return TEXT("Provider routing wrapper remains deferred; diagnostic packet was not emitted."); + return TEXT("Route inspection wrapper recorded a bounded failure before any diagnostic packet was emitted."); } return TEXT("Invocation failed before any product-truth output was emitted."); @@ -426,7 +556,7 @@ namespace HyperTwistSkillCoreLibraryInternal { if (Entry.SkillId == TEXT("skill/memory-resume-briefing")) { - return TEXT("User cancelled the bounded resume briefing before any derived output was promoted."); + return TEXT("User cancelled the bounded watch-and-recheck wrapper before any resume brief was promoted."); } return TEXT("Invocation cancelled before any product-truth output was emitted."); @@ -678,17 +808,17 @@ namespace HyperTwistSkillCoreLibraryInternal } } -FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistryState() + FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistryState() { using namespace HyperTwistSkillCoreLibraryInternal; FHyperTwistSkillRegistryState RegistryState; RegistryState.RegistryId = TEXT("skill-registry/first-party"); - RegistryState.ManifestVersion = TEXT("s1a-v1"); - RegistryState.ReferenceUtc = TEXT("2026-05-28T19:30:00Z"); + RegistryState.ManifestVersion = TEXT("s2a-v1"); + RegistryState.ReferenceUtc = TEXT("2026-05-28T23:55:00Z"); RegistryState.CommandSurfaceRootId = TEXT("command-surface/skills"); RegistryState.Summary = - TEXT("First-party skill registry and manifest contract declarations only."); + TEXT("First-party skill registry and manifest contract with landed permissive analyzer wrappers."); RegistryState.Entries = { MakeSkillEntry( @@ -738,17 +868,17 @@ FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistrySt TEXT("lane/skillization/analysis-review"), TEXT("feature/skills/review-analyzer"), EHyperTwistSkillFamily::AnalysisReview, - EHyperTwistSkillStatus::CommandContractPending, + EHyperTwistSkillStatus::ImplementedNow, false, true, { MakeCommandBinding( TEXT("command/skills/review-architecture"), - TEXT("service/deferred/review-architecture"), + TEXT("service/skills/review-architecture"), TEXT("feature/skills/review-analyzer"), - TEXT("deferred-wrapper"), - false, - TEXT("Permissive analyzer wrapper stays deferred until later skillization stages.") + TEXT("analyzer/architecture-and-policy-scan"), + true, + TEXT("Live first-party architecture and policy scan wrapper over permissive product evidence.") ) }, { @@ -767,11 +897,14 @@ FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistrySt }, MakeProvenanceDeclaration( EHyperTwistSkillLogPolicy::InvocationLedgerRequired, - {TEXT("artifact/review-report")}, + { + TEXT("artifact/architecture-scan"), + TEXT("artifact/policy-scan") + }, true, - TEXT("Review wrappers must emit provenance-visible reports once invocation logging lands.") + TEXT("Live review wrappers emit provenance-visible architecture and policy scan output.") ), - TEXT("Declared but not yet wrapped analyzer/review family.") + TEXT("Landed permissive architecture and policy scan wrapper family.") ), MakeSkillEntry( TEXT("skill/memory-resume-briefing"), @@ -779,17 +912,17 @@ FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistrySt TEXT("lane/skillization/memory-continuity"), TEXT("feature/skills/memory-resume"), EHyperTwistSkillFamily::MemoryContinuity, - EHyperTwistSkillStatus::CommandContractPending, + EHyperTwistSkillStatus::ImplementedNow, false, true, { MakeCommandBinding( TEXT("command/skills/memory-resume-briefing"), - TEXT("service/deferred/memory-resume-briefing"), + TEXT("service/skills/memory-resume-briefing"), TEXT("feature/skills/memory-resume"), - TEXT("deferred-wrapper"), - false, - TEXT("Future wrapper over the landed first-party memory seams.") + TEXT("analyzer/watch-and-recheck"), + true, + TEXT("Live watch-and-recheck wrapper over the landed first-party memory seams.") ) }, { @@ -808,11 +941,11 @@ FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistrySt }, MakeProvenanceDeclaration( EHyperTwistSkillLogPolicy::InvocationLedgerRequired, - {TEXT("artifact/resume-pack")}, + {TEXT("artifact/watch-and-recheck-brief")}, true, - TEXT("Shared resume packets must stay provenance-visible once wrappers land.") + TEXT("Watch-and-recheck briefs stay provenance-visible under the landed memory wrapper.") ), - TEXT("Declared memory/continuity skill family above the landed memory substrate.") + TEXT("Landed watch-and-recheck wrapper family above the landed memory substrate.") ), MakeSkillEntry( TEXT("skill/provider-routing-inspector"), @@ -820,17 +953,17 @@ FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistrySt TEXT("lane/skillization/provider-ops"), TEXT("feature/skills/provider-routing-inspector"), EHyperTwistSkillFamily::ProviderOperations, - EHyperTwistSkillStatus::CommandContractPending, + EHyperTwistSkillStatus::ImplementedNow, false, true, { MakeCommandBinding( TEXT("command/skills/provider-routing-inspector"), - TEXT("service/deferred/provider-routing-inspector"), + TEXT("service/skills/provider-routing-inspector"), TEXT("feature/skills/provider-routing-inspector"), - TEXT("deferred-wrapper"), - false, - TEXT("Future wrapper over landed provider-neutral speech/provider contracts.") + TEXT("analyzer/route-inspection"), + true, + TEXT("Live route-inspection wrapper over landed provider-neutral speech/provider contracts.") ) }, { @@ -849,11 +982,11 @@ FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistrySt }, MakeProvenanceDeclaration( EHyperTwistSkillLogPolicy::InvocationLedgerRequired, - {TEXT("artifact/provider-diagnostic-packet")}, + {TEXT("artifact/route-inspection-packet")}, true, - TEXT("Provider inspection output must stay provenance-visible once wrappers land.") + TEXT("Route-inspection output must stay provenance-visible under the landed provider wrapper.") ), - TEXT("Declared provider/ops family above the landed speech/provider seams.") + TEXT("Landed route-inspection wrapper family above the landed speech/provider seams.") ), MakeSkillEntry( TEXT("skill/roux-session-review"), @@ -952,8 +1085,7 @@ FHyperTwistSkillRegistryState UHyperTwistSkillCoreLibrary::DeriveSkillRegistrySt RegistryState.bNoAdHocMetadataRequired = true; RegistryState.StatusCounts = { - MakeStatusCount(EHyperTwistSkillStatus::ImplementedNow, 1), - MakeStatusCount(EHyperTwistSkillStatus::CommandContractPending, 3), + MakeStatusCount(EHyperTwistSkillStatus::ImplementedNow, 4), MakeStatusCount(EHyperTwistSkillStatus::CleanRoomSpecPending, 1), MakeStatusCount(EHyperTwistSkillStatus::PlaceholderFamily, 1) }; @@ -1315,3 +1447,94 @@ FHyperTwistSkillAuthoringHarnessState UHyperTwistSkillCoreLibrary::DeriveSkillAu return HarnessState; } + +FHyperTwistSkillAnalyzerWrapperState UHyperTwistSkillCoreLibrary::DeriveSkillAnalyzerWrapperState( + const FHyperTwistSkillRegistryState& RegistryState, + const FHyperTwistSkillControlState& ControlState, + const FHyperTwistSkillAuthoringHarnessState& AuthoringHarnessState +) +{ + using namespace HyperTwistSkillCoreLibraryInternal; + + if (!RegistryState.IsStructurallyValid() + || !ControlState.IsStructurallyValid() + || !AuthoringHarnessState.IsStructurallyValid() + || RegistryState.RegistryId != ControlState.RegistryId + || RegistryState.RegistryId != AuthoringHarnessState.RegistryId + || RegistryState.CommandSurfaceRootId != ControlState.CommandSurfaceRootId + || RegistryState.CommandSurfaceRootId != AuthoringHarnessState.CommandSurfaceRootId) + { + return FHyperTwistSkillAnalyzerWrapperState(); + } + + FHyperTwistSkillAnalyzerWrapperState WrapperState; + WrapperState.RegistryId = RegistryState.RegistryId; + WrapperState.ManifestVersion = TEXT("s2a-v1"); + WrapperState.ReferenceUtc = TEXT("2026-05-28T23:58:00Z"); + WrapperState.CommandSurfaceRootId = RegistryState.CommandSurfaceRootId; + WrapperState.TemplateVersion = AuthoringHarnessState.TemplateVersion; + WrapperState.bEveryWrapperMapsToStableInvocationPattern = true; + WrapperState.bEveryWrapperEmitsStructuredOutput = true; + WrapperState.bOnlyImplementedPermissiveWrappersIncluded = true; + WrapperState.Summary = + TEXT("First-party permissive analyzer wrappers over landed HyperTwist seams."); + + for (const FHyperTwistSkillManifestEntry& Entry : RegistryState.Entries) + { + if (Entry.Status != EHyperTwistSkillStatus::ImplementedNow + || !IsPermissiveAnalyzerWrapperSkill(Entry.SkillId)) + { + continue; + } + + const FHyperTwistSkillControlStateEntry* ControlEntry = + FindControlStateEntryById(ControlState, Entry.SkillId); + const FHyperTwistSkillAuthoringExampleState* ExampleState = + FindAuthoringExampleBySkillId(AuthoringHarnessState, Entry.SkillId); + if (ControlEntry == nullptr + || !ControlEntry->IsStructurallyValid() + || !ControlEntry->bInstalled + || !ControlEntry->bOptionalAssistive + || ExampleState == nullptr + || !ExampleState->IsStructurallyValid() + || !HasLiveEvalValidationCase(AuthoringHarnessState, Entry.SkillId)) + { + return FHyperTwistSkillAnalyzerWrapperState(); + } + + for (const FString& ArtifactKind : Entry.Provenance.ProducedArtifactKinds) + { + const FHyperTwistSkillAnalyzerWrapperOutput Output = + MakeAnalyzerWrapperOutput(Entry, ArtifactKind); + if (!Output.IsStructurallyValid()) + { + return FHyperTwistSkillAnalyzerWrapperState(); + } + + WrapperState.Outputs.Add(Output); + WrapperState.ArchitectureScanCount += + Output.OutputKindId == TEXT("wrapper-output/architecture-scan") ? 1 : 0; + WrapperState.PolicyScanCount += + Output.OutputKindId == TEXT("wrapper-output/policy-scan") ? 1 : 0; + WrapperState.RouteInspectionCount += + Output.OutputKindId == TEXT("wrapper-output/route-inspection") ? 1 : 0; + WrapperState.WatchAndRecheckCount += + Output.OutputKindId == TEXT("wrapper-output/watch-and-recheck") ? 1 : 0; + } + } + + TArray ImplementedSkillIds; + for (const FHyperTwistSkillAnalyzerWrapperOutput& Output : WrapperState.Outputs) + { + ImplementedSkillIds.AddUnique(Output.SkillId); + WrapperState.bEveryWrapperMapsToStableInvocationPattern &= Output.bStableInvocationPattern; + WrapperState.bEveryWrapperEmitsStructuredOutput &= Output.bStructuredOutput; + WrapperState.bOnlyImplementedPermissiveWrappersIncluded &= + IsPermissiveAnalyzerWrapperSkill(Output.SkillId); + } + + WrapperState.SkillCount = ImplementedSkillIds.Num(); + WrapperState.OutputCount = WrapperState.Outputs.Num(); + + return WrapperState; +} diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h index 9961481..66f877d 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistBootstrap/HyperTwistContractLibrary.h @@ -179,6 +179,9 @@ public: UFUNCTION(BlueprintPure, Category = "HyperTwist|Skills") static FHyperTwistSkillAuthoringHarnessState MakeSampleSkillAuthoringHarnessState(); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Skills") + static FHyperTwistSkillAnalyzerWrapperState MakeSampleSkillAnalyzerWrapperState(); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Training") static FHyperTwistTrainingRepositoryIntegrityReport MakeSampleTrainingRepositoryIntegrityReport(); @@ -388,6 +391,11 @@ public: const FHyperTwistSkillAuthoringHarnessState& SkillAuthoringHarnessState ); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Serialization") + static FString SerializeSkillAnalyzerWrapperStateToJson( + const FHyperTwistSkillAnalyzerWrapperState& SkillAnalyzerWrapperState + ); + UFUNCTION(BlueprintPure, Category = "HyperTwist|Serialization") static FString SerializeTrainingTimerExportPacketToJson(const FHyperTwistTrainingTimerExportPacket& TimerExportPacket); @@ -484,6 +492,12 @@ public: FHyperTwistSkillAuthoringHarnessState& OutSkillAuthoringHarnessState ); + UFUNCTION(BlueprintCallable, Category = "HyperTwist|Serialization") + static bool DeserializeSkillAnalyzerWrapperStateFromJson( + const FString& Json, + FHyperTwistSkillAnalyzerWrapperState& OutSkillAnalyzerWrapperState + ); + 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 4f4b6bd..b029117 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillCoreLibrary.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillCoreLibrary.h @@ -32,4 +32,11 @@ public: const FHyperTwistSkillControlState& ControlState, const FHyperTwistSkillAuditLedgerState& AuditLedgerState ); + + UFUNCTION(BlueprintPure, Category = "HyperTwist|Skills") + static FHyperTwistSkillAnalyzerWrapperState DeriveSkillAnalyzerWrapperState( + const FHyperTwistSkillRegistryState& RegistryState, + const FHyperTwistSkillControlState& ControlState, + const FHyperTwistSkillAuthoringHarnessState& AuthoringHarnessState + ); }; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillTypes.h b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillTypes.h index 274aeca..520f885 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillTypes.h +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Public/HyperTwistSkills/HyperTwistSkillTypes.h @@ -1620,3 +1620,219 @@ struct FHyperTwistSkillAuthoringHarnessState == bComputedValidationUsesAuditLedgerWhenLive; } }; + +USTRUCT(BlueprintType) +struct FHyperTwistSkillAnalyzerWrapperOutput +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString WrapperOutputId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString SkillId; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString DisplayLabel; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString OutputKindId; + + 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") + FString ArtifactKind; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + TArray PermissionScopeIds; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bLiveWrapper = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bStableInvocationPattern = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bStructuredOutput = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bDerivedAssistiveOnly = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Summary; + + bool IsStructurallyValid() const + { + if (WrapperOutputId.IsEmpty() + || SkillId.IsEmpty() + || DisplayLabel.IsEmpty() + || OutputKindId.IsEmpty() + || CommandSurfaceId.IsEmpty() + || ServiceBindingId.IsEmpty() + || OwnerLaneId.IsEmpty() + || OwnerFeatureId.IsEmpty() + || ArtifactKind.IsEmpty() + || PermissionScopeIds.Num() == 0 + || !bLiveWrapper + || !bStableInvocationPattern + || !bStructuredOutput + || !bDerivedAssistiveOnly) + { + return false; + } + + for (const FString& ScopeId : PermissionScopeIds) + { + if (ScopeId.IsEmpty()) + { + return false; + } + } + + return true; + } +}; + +USTRUCT(BlueprintType) +struct FHyperTwistSkillAnalyzerWrapperState +{ + 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 Outputs; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 SkillCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 OutputCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 ArchitectureScanCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 PolicyScanCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 RouteInspectionCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + int32 WatchAndRecheckCount = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bEveryWrapperMapsToStableInvocationPattern = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bEveryWrapperEmitsStructuredOutput = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + bool bOnlyImplementedPermissiveWrappersIncluded = false; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist") + FString Summary; + + bool IsStructurallyValid() const + { + if (RegistryId.IsEmpty() + || ManifestVersion.IsEmpty() + || ReferenceUtc.IsEmpty() + || CommandSurfaceRootId.IsEmpty() + || TemplateVersion.IsEmpty() + || Outputs.Num() == 0 + || SkillCount <= 0 + || OutputCount != Outputs.Num() + || ArchitectureScanCount < 0 + || PolicyScanCount < 0 + || RouteInspectionCount < 0 + || WatchAndRecheckCount < 0 + || !bEveryWrapperMapsToStableInvocationPattern + || !bEveryWrapperEmitsStructuredOutput + || !bOnlyImplementedPermissiveWrappersIncluded) + { + return false; + } + + TArray SeenOutputIds; + TArray SeenSkillIds; + int32 ComputedArchitectureScanCount = 0; + int32 ComputedPolicyScanCount = 0; + int32 ComputedRouteInspectionCount = 0; + int32 ComputedWatchAndRecheckCount = 0; + bool bComputedStableInvocationPattern = true; + bool bComputedStructuredOutput = true; + bool bComputedOnlyImplementedPermissiveWrappersIncluded = true; + + for (const FHyperTwistSkillAnalyzerWrapperOutput& Output : Outputs) + { + if (!Output.IsStructurallyValid() || SeenOutputIds.Contains(Output.WrapperOutputId)) + { + return false; + } + + SeenOutputIds.Add(Output.WrapperOutputId); + SeenSkillIds.AddUnique(Output.SkillId); + bComputedStableInvocationPattern &= Output.bStableInvocationPattern; + bComputedStructuredOutput &= Output.bStructuredOutput; + bComputedOnlyImplementedPermissiveWrappersIncluded &= + Output.SkillId == TEXT("skill/review-architecture") + || Output.SkillId == TEXT("skill/memory-resume-briefing") + || Output.SkillId == TEXT("skill/provider-routing-inspector"); + + if (Output.OutputKindId == TEXT("wrapper-output/architecture-scan")) + { + ComputedArchitectureScanCount += 1; + } + else if (Output.OutputKindId == TEXT("wrapper-output/policy-scan")) + { + ComputedPolicyScanCount += 1; + } + else if (Output.OutputKindId == TEXT("wrapper-output/route-inspection")) + { + ComputedRouteInspectionCount += 1; + } + else if (Output.OutputKindId == TEXT("wrapper-output/watch-and-recheck")) + { + ComputedWatchAndRecheckCount += 1; + } + else + { + return false; + } + } + + return SkillCount == SeenSkillIds.Num() + && ArchitectureScanCount == ComputedArchitectureScanCount + && PolicyScanCount == ComputedPolicyScanCount + && RouteInspectionCount == ComputedRouteInspectionCount + && WatchAndRecheckCount == ComputedWatchAndRecheckCount + && bEveryWrapperMapsToStableInvocationPattern == bComputedStableInvocationPattern + && bEveryWrapperEmitsStructuredOutput == bComputedStructuredOutput + && bOnlyImplementedPermissiveWrappersIncluded + == bComputedOnlyImplementedPermissiveWrappersIncluded; + } +}; diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1ARegistryManifestContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1ARegistryManifestContractTest.cpp index 7eef5fe..8b6d6ad 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1ARegistryManifestContractTest.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1ARegistryManifestContractTest.cpp @@ -86,20 +86,12 @@ bool FHyperTwistSkillPhaseS1ARegistryManifestTest::RunTest(const FString& Parame RegistryState.bAllSkillsOptionalAssistive ); TestEqual( - TEXT("The sample S1-A registry must keep one implemented skill entry."), + TEXT("The sample S1-A registry must keep four implemented skill entries after S2-A lands."), HyperTwistSkillPhaseS1ATestInternal::FindStatusCount( RegistryState, EHyperTwistSkillStatus::ImplementedNow ), - 1 - ); - TestEqual( - TEXT("The sample S1-A registry must keep three command-contract-pending entries."), - HyperTwistSkillPhaseS1ATestInternal::FindStatusCount( - RegistryState, - EHyperTwistSkillStatus::CommandContractPending - ), - 3 + 4 ); TestEqual( TEXT("The sample S1-A registry must expose one governance-family entry."), @@ -166,33 +158,33 @@ bool FHyperTwistSkillPhaseS1ADisabledSkillsRemainInstalledTest::RunTest( RegistryState.DisabledByDefaultCount > 0 ); - const FHyperTwistSkillManifestEntry* DeferredProviderSkill = + const FHyperTwistSkillManifestEntry* ProviderSkill = HyperTwistSkillPhaseS1ATestInternal::FindSkillById( RegistryState, TEXT("skill/provider-routing-inspector") ); TestNotNull( TEXT("A disabled provider-routing-inspector skill must exist."), - DeferredProviderSkill + ProviderSkill ); - if (DeferredProviderSkill != nullptr) + if (ProviderSkill != nullptr) { TestFalse( - TEXT("The deferred provider skill must start disabled by default."), - DeferredProviderSkill->bEnabledByDefault + TEXT("The provider skill must start disabled by default."), + ProviderSkill->bEnabledByDefault ); TestTrue( - TEXT("The deferred provider skill must remain installed when disabled."), - DeferredProviderSkill->bInstalledWhenDisabled + TEXT("The provider skill must remain installed when disabled."), + ProviderSkill->bInstalledWhenDisabled ); TestTrue( - TEXT("The deferred provider skill must stay inert when disabled."), - DeferredProviderSkill->bInertWhenDisabled + TEXT("The provider skill must stay inert when disabled."), + ProviderSkill->bInertWhenDisabled ); TestEqual( - TEXT("The deferred provider skill must stay command-contract pending."), - DeferredProviderSkill->Status, - EHyperTwistSkillStatus::CommandContractPending + TEXT("The provider skill must now be implemented while remaining opt-in."), + ProviderSkill->Status, + EHyperTwistSkillStatus::ImplementedNow ); } diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1CInvocationAuditLedgerContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1CInvocationAuditLedgerContractTest.cpp index 4f5a5cc..522d24e 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1CInvocationAuditLedgerContractTest.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1CInvocationAuditLedgerContractTest.cpp @@ -111,12 +111,12 @@ bool FHyperTwistSkillPhaseS1CFailureCancelRecordingTest::RunTest(const FString& TestEqual( TEXT("The sample audit ledger should contain the expected successful invocation count."), AuditLedgerState.SuccessfulInvocationCount, - 1 + 2 ); TestEqual( TEXT("The sample audit ledger should contain the expected failed invocation count."), AuditLedgerState.FailedInvocationCount, - 2 + 1 ); TestEqual( TEXT("The sample audit ledger should contain the expected cancelled invocation count."), @@ -136,17 +136,40 @@ bool FHyperTwistSkillPhaseS1CFailureCancelRecordingTest::RunTest(const FString& if (ReviewRecord != nullptr) { TestEqual( - TEXT("The review skill should record a failure outcome."), + TEXT("The review skill should now record a success outcome."), ReviewRecord->Outcome, - EHyperTwistSkillInvocationOutcome::Failed - ); - TestFalse( - TEXT("Failed review invocations should not emit product-truth output."), - ReviewRecord->bOutputBecameProductTruth + EHyperTwistSkillInvocationOutcome::Succeeded ); TestTrue( - TEXT("Failed review invocations should preserve a failure reason."), - !ReviewRecord->FailureReason.IsEmpty() + TEXT("Successful review invocations should emit traceable product output."), + ReviewRecord->bOutputBecameProductTruth && ReviewRecord->bOutputTraceable + ); + TestEqual( + TEXT("The review wrapper should emit the architecture and policy scan artifacts."), + ReviewRecord->ProducedArtifacts.Num(), + 2 + ); + } + + const FHyperTwistSkillInvocationRecord* ProviderRecord = + HyperTwistSkillPhaseS1CTestInternal::FindInvocationRecordBySkillId( + AuditLedgerState, + TEXT("skill/provider-routing-inspector") + ); + TestNotNull( + TEXT("The provider skill invocation should be present in the sample audit ledger."), + ProviderRecord + ); + if (ProviderRecord != nullptr) + { + TestEqual( + TEXT("The provider skill should still exercise failure recording."), + ProviderRecord->Outcome, + EHyperTwistSkillInvocationOutcome::Failed + ); + TestTrue( + TEXT("Failed provider invocations should preserve a failure reason."), + !ProviderRecord->FailureReason.IsEmpty() ); } @@ -162,7 +185,7 @@ bool FHyperTwistSkillPhaseS1CFailureCancelRecordingTest::RunTest(const FString& if (MemoryRecord != nullptr) { TestEqual( - TEXT("The memory skill should record a cancelled outcome."), + TEXT("The memory skill should still record a cancelled outcome."), MemoryRecord->Outcome, EHyperTwistSkillInvocationOutcome::Cancelled ); diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1DAuthoringValidationHarnessContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1DAuthoringValidationHarnessContractTest.cpp index d08ff67..8fbd82c 100644 --- a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1DAuthoringValidationHarnessContractTest.cpp +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS1DAuthoringValidationHarnessContractTest.cpp @@ -148,9 +148,9 @@ bool FHyperTwistSkillPhaseS1DValidationHarnessCoverageTest::RunTest(const FStrin if (ReviewEval != nullptr) { TestEqual( - TEXT("The review skill eval contract should stay deferred until wrappers land."), + TEXT("The review skill eval contract should now run live after S2-A lands."), ReviewEval->ExecutionMode, - EHyperTwistSkillValidationExecutionMode::DeferredUntilWrapper + EHyperTwistSkillValidationExecutionMode::LiveContract ); } diff --git a/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS2APermissiveAnalyzerWrapperContractTest.cpp b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS2APermissiveAnalyzerWrapperContractTest.cpp new file mode 100644 index 0000000..9fe85e0 --- /dev/null +++ b/UnrealHyperTwist/Source/UnrealHyperTwist/Tests/HyperTwistSkillPhaseS2APermissiveAnalyzerWrapperContractTest.cpp @@ -0,0 +1,210 @@ +#include "Misc/AutomationTest.h" + +#include "HyperTwistBootstrap/HyperTwistContractLibrary.h" + +namespace HyperTwistSkillPhaseS2ATestInternal +{ + const FHyperTwistSkillAnalyzerWrapperOutput* FindOutputByKind( + const FHyperTwistSkillAnalyzerWrapperState& WrapperState, + const FString& OutputKindId + ) + { + for (const FHyperTwistSkillAnalyzerWrapperOutput& Output : WrapperState.Outputs) + { + if (Output.OutputKindId == OutputKindId) + { + return &Output; + } + } + + return nullptr; + } +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistSkillPhaseS2AWrapperCoverageTest, + "HyperTwist.FirstParty.Skill.PhaseS2A.WrapperCoverage", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistSkillPhaseS2AWrapperCoverageTest::RunTest(const FString& Parameters) +{ + const FHyperTwistSkillAnalyzerWrapperState WrapperState = + UHyperTwistContractLibrary::MakeSampleSkillAnalyzerWrapperState(); + + TestTrue( + TEXT("The sample S2-A analyzer wrapper state should be structurally valid."), + WrapperState.IsStructurallyValid() + ); + TestEqual( + TEXT("S2-A should land three implemented permissive wrapper skills."), + WrapperState.SkillCount, + 3 + ); + TestEqual( + TEXT("S2-A should expose four structured wrapper outputs."), + WrapperState.OutputCount, + 4 + ); + TestEqual( + TEXT("S2-A should expose one architecture scan output."), + WrapperState.ArchitectureScanCount, + 1 + ); + TestEqual( + TEXT("S2-A should expose one policy scan output."), + WrapperState.PolicyScanCount, + 1 + ); + TestEqual( + TEXT("S2-A should expose one route inspection output."), + WrapperState.RouteInspectionCount, + 1 + ); + TestEqual( + TEXT("S2-A should expose one watch-and-recheck output."), + WrapperState.WatchAndRecheckCount, + 1 + ); + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistSkillPhaseS2AStableInvocationPatternTest, + "HyperTwist.FirstParty.Skill.PhaseS2A.StableInvocationPatterns", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistSkillPhaseS2AStableInvocationPatternTest::RunTest(const FString& Parameters) +{ + const FHyperTwistSkillAnalyzerWrapperState WrapperState = + UHyperTwistContractLibrary::MakeSampleSkillAnalyzerWrapperState(); + + TestTrue( + TEXT("The sample S2-A analyzer wrapper state should be structurally valid."), + WrapperState.IsStructurallyValid() + ); + TestTrue( + TEXT("Every S2-A wrapper should map to a stable invocation pattern."), + WrapperState.bEveryWrapperMapsToStableInvocationPattern + ); + TestTrue( + TEXT("Every S2-A wrapper should emit structured output."), + WrapperState.bEveryWrapperEmitsStructuredOutput + ); + TestTrue( + TEXT("S2-A should only include implemented permissive wrappers."), + WrapperState.bOnlyImplementedPermissiveWrappersIncluded + ); + + const FHyperTwistSkillAnalyzerWrapperOutput* ArchitectureOutput = + HyperTwistSkillPhaseS2ATestInternal::FindOutputByKind( + WrapperState, + TEXT("wrapper-output/architecture-scan") + ); + TestNotNull( + TEXT("The architecture scan output should exist."), + ArchitectureOutput + ); + if (ArchitectureOutput != nullptr) + { + TestEqual( + TEXT("Architecture scan should be emitted by the review-architecture wrapper."), + ArchitectureOutput->SkillId, + FString(TEXT("skill/review-architecture")) + ); + TestEqual( + TEXT("Architecture scan should use the live review wrapper service."), + ArchitectureOutput->ServiceBindingId, + FString(TEXT("service/skills/review-architecture")) + ); + } + + const FHyperTwistSkillAnalyzerWrapperOutput* RouteOutput = + HyperTwistSkillPhaseS2ATestInternal::FindOutputByKind( + WrapperState, + TEXT("wrapper-output/route-inspection") + ); + TestNotNull( + TEXT("The route inspection output should exist."), + RouteOutput + ); + if (RouteOutput != nullptr) + { + TestEqual( + TEXT("Route inspection should be emitted by the provider-routing-inspector wrapper."), + RouteOutput->SkillId, + FString(TEXT("skill/provider-routing-inspector")) + ); + } + + const FHyperTwistSkillAnalyzerWrapperOutput* WatchOutput = + HyperTwistSkillPhaseS2ATestInternal::FindOutputByKind( + WrapperState, + TEXT("wrapper-output/watch-and-recheck") + ); + TestNotNull( + TEXT("The watch-and-recheck output should exist."), + WatchOutput + ); + if (WatchOutput != nullptr) + { + TestEqual( + TEXT("Watch-and-recheck should be emitted by the memory-resume-briefing wrapper."), + WatchOutput->SkillId, + FString(TEXT("skill/memory-resume-briefing")) + ); + } + + return true; +} + +IMPLEMENT_SIMPLE_AUTOMATION_TEST( + FHyperTwistSkillPhaseS2ASerializationRoundTripTest, + "HyperTwist.FirstParty.Skill.PhaseS2A.SerializationRoundTrip", + EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter +) + +bool FHyperTwistSkillPhaseS2ASerializationRoundTripTest::RunTest(const FString& Parameters) +{ + const FHyperTwistSkillAnalyzerWrapperState WrapperState = + UHyperTwistContractLibrary::MakeSampleSkillAnalyzerWrapperState(); + + TestTrue( + TEXT("The sample S2-A analyzer wrapper state should be structurally valid before serialization."), + WrapperState.IsStructurallyValid() + ); + + const FString Json = + UHyperTwistContractLibrary::SerializeSkillAnalyzerWrapperStateToJson(WrapperState); + TestTrue( + TEXT("Serialized S2-A wrapper JSON should include the structured-output guard field."), + Json.Contains(TEXT("bEveryWrapperEmitsStructuredOutput")) + ); + + FHyperTwistSkillAnalyzerWrapperState RoundTrippedState; + TestTrue( + TEXT("Deserializing the S2-A wrapper JSON should succeed."), + UHyperTwistContractLibrary::DeserializeSkillAnalyzerWrapperStateFromJson( + Json, + RoundTrippedState + ) + ); + TestTrue( + TEXT("Round-tripped S2-A wrapper state should remain structurally valid."), + RoundTrippedState.IsStructurallyValid() + ); + TestEqual( + TEXT("Round-tripped S2-A skill count should match the original sample."), + RoundTrippedState.SkillCount, + WrapperState.SkillCount + ); + TestEqual( + TEXT("Round-tripped S2-A output count should match the original sample."), + RoundTrippedState.OutputCount, + WrapperState.OutputCount + ); + + return true; +} diff --git a/docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_IMPLEMENTATION_PACKET_2026-05-28.md b/docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_IMPLEMENTATION_PACKET_2026-05-28.md new file mode 100644 index 0000000..5b3afa5 --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_IMPLEMENTATION_PACKET_2026-05-28.md @@ -0,0 +1,100 @@ +# HyperTwist Phase S2-A first-party permissive analyzer wrappers implementation packet + +Created on `2026-05-28` + +## Status + +- first-party HyperTwist packet +- bounded `Phase S2-A` implementation slice + +## Purpose + +This packet lands the bounded first-party permissive analyzer wrapper seam +under the canonical `Skillization And Command Surface` doctrine. + +The landed slice is: + +- architecture scan +- policy scan +- route inspection +- watch-and-recheck + +It is not: + +- restrictive clean-room command-contract specs +- broader memory, provider, browser, workflow, or domain skill widening +- donor command promotion + +## Current authority basis + +This implementation packet stands on: + +- `docs/ops/HYPERTWIST_SKILLIZATION_AND_COMMAND_SURFACE_DOCTRINE_2026-05-21.md` +- `docs/ops/HYPERTWIST_OPTIONAL_ASSISTIVE_FEATURE_DEACTIVATION_AND_REMOVABILITY_DOCTRINE_2026-05-21.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/SKILLS.md` +- `docs/v6_5_deep_manual_pack/HyperTwist/PROVENANCE_AND_TRUST_MODEL.md` +- `docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_PREPARATION_PACKET_2026-05-28.md` + +## Landed scope + +The current code now owns a bounded first-party permissive wrapper seam +through: + +- live registry promotion for: + - `skill/review-architecture` + - `skill/memory-resume-briefing` + - `skill/provider-routing-inspector` +- stable first-party command/service bindings for: + - architecture scan + - policy scan + - route inspection + - watch-and-recheck +- canonical structured wrapper-output and aggregate wrapper-state contracts in: + - `HyperTwistSkillTypes.h` +- first-party wrapper-state derivation over the landed registry, control-state, + and authoring-harness seams in: + - `UHyperTwistSkillCoreLibrary` +- sample contract helpers in: + - `UHyperTwistContractLibrary::MakeSampleSkillAnalyzerWrapperState()` + - `UHyperTwistContractLibrary::SerializeSkillAnalyzerWrapperStateToJson(...)` + - `UHyperTwistContractLibrary::DeserializeSkillAnalyzerWrapperStateFromJson(...)` +- focused automation coverage in: + - `HyperTwistSkillPhaseS2APermissiveAnalyzerWrapperContractTest.cpp` + +## Why this is still intentionally bounded + +This packet lands permissive first-party wrapper contracts only. + +Still deferred: + +- restrictive clean-room command-contract specs +- broader memory, provider, browser, workflow, and domain skill widening + +## Validation + +Build validation: + +- `UnrealHyperTwistEditor Win64 Development` + +Focused automation validation: + +- `HyperTwist.FirstParty.Skill.PhaseS2A.WrapperCoverage` +- `HyperTwist.FirstParty.Skill.PhaseS2A.StableInvocationPatterns` +- `HyperTwist.FirstParty.Skill.PhaseS2A.SerializationRoundTrip` + +Observed: + +- `3` focused `Phase S2-A` automation tests succeeded + +## Queue effect + +This packet consumes the current `Phase S2-A` implementation slice. + +After this landing: + +- `S2-A` is landed in current code +- `S2-B` is the next clean skillization move +- broader wrapper widening still remains deferred behind `S2-B` diff --git a/docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_PREPARATION_PACKET_2026-05-28.md b/docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_PREPARATION_PACKET_2026-05-28.md new file mode 100644 index 0000000..8163dbf --- /dev/null +++ b/docs/arch/HYPERTWIST_PHASES2_A_FIRST_PARTY_PERMISSIVE_ANALYZER_WRAPPERS_PREPARATION_PACKET_2026-05-28.md @@ -0,0 +1,95 @@ +# HyperTwist Phase S2-A first-party permissive analyzer wrappers preparation packet + +Created on `2026-05-28` + +## Status + +- first-party HyperTwist packet +- source-backed `Phase S2-A` preparation/control slice + +## Purpose + +This packet scopes the first bounded wrapper slice under the canonical +`Skillization And Command Surface` doctrine. + +The granted slice is: + +- architecture scan +- policy scan +- route inspection +- watch-and-recheck + +It is not: + +- restrictive clean-room command-contract specs +- broader memory, provider, browser, workflow, or domain skill widening +- donor command promotion + +## Current authority basis + +This control pass stands on: + +- `docs/ops/HYPERTWIST_SKILLIZATION_AND_COMMAND_SURFACE_DOCTRINE_2026-05-21.md` +- `docs/ops/HYPERTWIST_OPTIONAL_ASSISTIVE_FEATURE_DEACTIVATION_AND_REMOVABILITY_DOCTRINE_2026-05-21.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/SKILLS.md` +- `docs/v6_5_deep_manual_pack/HyperTwist/PROVENANCE_AND_TRUST_MODEL.md` +- `docs/arch/HYPERTWIST_PHASES1_A_FIRST_PARTY_SKILL_REGISTRY_AND_MANIFEST_CONTRACT_IMPLEMENTATION_PACKET_2026-05-28.md` +- `docs/arch/HYPERTWIST_PHASES1_B_FIRST_PARTY_SKILL_SETTINGS_MENU_AND_OFF_STATE_CONTROL_IMPLEMENTATION_PACKET_2026-05-28.md` +- `docs/arch/HYPERTWIST_PHASES1_C_FIRST_PARTY_SKILL_INVOCATION_PROVENANCE_AND_AUDIT_LEDGER_IMPLEMENTATION_PACKET_2026-05-28.md` +- `docs/arch/HYPERTWIST_PHASES1_D_FIRST_PARTY_SKILL_AUTHORING_EXAMPLES_AND_VALIDATION_HARNESS_IMPLEMENTATION_PACKET_2026-05-28.md` + +## Granted family + +The bounded `Phase S2-A` slice may land: + +1. live first-party review/analyzer wrapper bindings +2. live first-party watch-and-recheck wrapper binding above landed memory seams +3. live first-party route-inspection wrapper binding above landed provider seams +4. structured wrapper-output contract state plus JSON round-trip coverage + +The packet must stay out of: + +- restrictive clean-room command specs +- user-authored note capture widening +- provider-specific overlays or broad provider settings ownership +- broader domain skill packs + +## Proposed implementation shape + +Land the narrower first-party boundary through: + +- registry promotion for the already-declared permissive wrapper skills +- stable first-party command/service binding updates for: + - `skill/review-architecture` + - `skill/memory-resume-briefing` + - `skill/provider-routing-inspector` +- structured wrapper-output types and aggregate wrapper state +- first-party skill-core derivation over the landed registry, control, and + authoring-harness seams +- sample contract helpers for: + - wrapper-state derivation + - JSON serialization + - JSON deserialization +- focused automation in: + - `HyperTwistSkillPhaseS2APermissiveAnalyzerWrapperContractTest.cpp` + +## Validation target + +Validate with: + +- Unreal build for `UnrealHyperTwistEditor Win64 Development` +- focused automation: + - `HyperTwist.FirstParty.Skill.PhaseS2A.WrapperCoverage` + - `HyperTwist.FirstParty.Skill.PhaseS2A.StableInvocationPatterns` + - `HyperTwist.FirstParty.Skill.PhaseS2A.SerializationRoundTrip` + +## Queue effect + +If this packet lands cleanly: + +- `S2-A` is consumed +- `S2-B` becomes the next clean move +- broader wrapper widening still remains deferred behind `S2-B` diff --git a/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md b/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md index 2f91d02..f805c0c 100644 --- a/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md +++ b/docs/ops/HYPERTWIST_IMPLEMENTATION_PHASE_1_KICKOFF.md @@ -279,5 +279,6 @@ Specifically: packet is now landed in current code - the bounded first-party `Phase S1-D` authoring/examples/validation-harness packet is now landed in current code -- `S2-A` permissive analyzer wrappers are the next clean move -- `S2-B` clean-room command-contract specs stay deferred until `S2-A` +- the bounded first-party `Phase S2-A` permissive analyzer wrapper packet is + now landed in current code +- `S2-B` clean-room command-contract specs 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 65ae094..656170d 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 @@ -227,7 +227,8 @@ Current state: is now landed in current code - the bounded first-party `Phase S1-C` invocation/provenance/audit-ledger packet is now landed in current code -- analyzer wrappers remain deferred to `S2-A` +- the bounded first-party `Phase S2-A` permissive analyzer wrapper packet is + now landed in current code #### `S1-C` invocation, provenance, and audit ledger @@ -247,7 +248,8 @@ Current state: packet is now landed in current code - the bounded first-party `Phase S1-D` authoring/examples/validation-harness packet is now landed in current code -- analyzer wrappers remain deferred to `S2-A` +- the bounded first-party `Phase S2-A` permissive analyzer wrapper packet is + now landed in current code #### `S1-D` authoring, examples, and validation harness @@ -265,7 +267,8 @@ Current state: - the bounded first-party `Phase S1-D` authoring/examples/validation-harness packet is now landed in current code -- analyzer wrappers remain deferred to `S2-A` +- the bounded first-party `Phase S2-A` permissive analyzer wrapper packet is + now landed in current code - restrictive clean-room command-contract specs remain deferred to `S2-B` ### S2 - refactor and analyzer skills @@ -286,6 +289,13 @@ Acceptance gates: - each skill maps to a stable first-party invocation pattern - each skill can surface structured output +Current state: + +- the bounded first-party `Phase S2-A` packet is now landed in current code +- review/analyzer wrappers now own architecture scan and policy scan output +- provider/ops wrappers now own route inspection output +- memory/continuity wrappers now own watch-and-recheck output + #### `S2-B` clean-room command-contract spec Scope: @@ -481,8 +491,8 @@ These are target-shape command families, not claims of implemented reality. The next correct sequence is: -1. `S2-A` permissive analyzer wrappers -2. `S2-B` clean-room command-contract specs for restrictive lanes +1. `S2-B` clean-room command-contract specs for restrictive lanes +2. broader memory, browser, workflow, provider, and domain skill widening Broader memory, browser, workflow, provider, and domain skill widening should wait until that base exists. diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md b/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md index dd8d6e4..e5a7b59 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/ARCHITECTURE.md @@ -245,4 +245,5 @@ Future skill growth must follow: - the bounded first-party `Phase S1-D` authoring/examples/validation-harness seam is now the live product base for adding new skills without inventing fresh structure -- `S2-A` remains the next clean move before wrapper widening +- the bounded first-party `Phase S2-A` permissive analyzer wrapper seam is + now the live product base before restrictive command-spec widening 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 4856d7e..58a9dba 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md @@ -304,10 +304,10 @@ 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`, and `Phase S1-D` 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, and per-skill smoke/eval validation-harness contracts are live. Permissive analyzer wrappers remain the next bounded skillization seam. | -| Review/analyzer skill family | Deep-source grounded retained | skillization doctrine | Planned after substrate and off-state controls. | -| Memory/continuity skill family | Deep-source grounded retained | skillization + memory doctrine | Retained, not implemented. | -| Provider/ops skill family | Deep-source grounded retained | skillization + provider doctrine | Retained, not implemented. | +| 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`, and `Phase S2-A` 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, and structured permissive wrapper-output contracts are live. `S2-B` 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 | Deep-source grounded retained + bounded live wrapper | landed first-party `Phase S2-A` packet + skillization + memory doctrine | Current bounded watch-and-recheck wrapper output is live above the landed first-party memory seams, while broader memory/continuity skill widening still remains retained. | +| 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. | | Domain/creative skill packs | Shallow placeholder | skillization doctrine only | Keep internal until source-grounded. | ## Shallow-known placeholder families 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 d8cac8f..2d46660 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 @@ -106,8 +106,12 @@ The landed bounded first-party `Phase S1-A` packet keeps: - the landed bounded first-party `Phase S1-B` packet keeps durable master and per-skill off-state control first-party rather than hidden prompt babysitting - the landed bounded first-party `Phase S1-D` packet now keeps authoring - template, registry-grounded examples, and smoke/eval validation structure + template, registry-grounded examples, and smoke/eval validation structure first-party before wrappers land +- the landed bounded first-party `Phase S2-A` packet now keeps structured + architecture scan, policy scan, route inspection, and watch-and-recheck + wrapper outputs provenance-visible through first-party command/service + bindings rather than deferred wrapper prose ## 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 8a8c86c..e26243b 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/ROADMAP.md @@ -173,6 +173,11 @@ Canonical discovery surfaces for roadmap interpretation: control pass is now consumed - the bounded first-party `Phase S1-D` authoring/examples/validation-harness packet is now landed in current code +- the generic first-party `Phase S2-A` permissive analyzer wrapper control + pass is now consumed +- the bounded first-party `Phase S2-A` permissive analyzer wrapper packet is + now landed in current code +- `S2-B` clean-room command-contract specs 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 811c102..2ffab0f 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/SKILLS.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/SKILLS.md @@ -70,7 +70,7 @@ Includes: Status: -- Deep-source grounded retained +- Implemented now Includes: @@ -82,7 +82,7 @@ Includes: Status: -- Deep-source grounded retained +- Deep-source grounded retained with bounded live wrapper Includes: @@ -94,7 +94,7 @@ Includes: Status: -- Deep-source grounded retained +- Deep-source grounded retained with bounded live wrapper Includes: