From 2bd12a0c5ef159f86a5c6c143e20f148da25dd18 Mon Sep 17 00:00:00 2001 From: axiomlogicnexus Date: Tue, 30 Jun 2026 11:47:41 +0000 Subject: [PATCH] Harden exact-source validation recovery --- .../Browser-ExactSource-20260630/index.json | 419 ++++++++++++++++++ ...ated_family_package_validation_report.json | 28 +- ...DOWS_BUILD_LANE_VERIFICATION_2026-06-01.md | 79 ++++ ...BUILD_VALIDATION_REQUIREMENT_2026-06-01.md | 24 + .../HyperTwist/DEVELOPMENT.md | 113 +++++ .../HyperTwist/FEATURE_REGISTRY.md | 2 +- ...te-exact-source-browser-package-refresh.sh | 412 +++++++++++++++++ ...run-hypertwist-remote-unreal-automation.sh | 27 +- scripts/run-hypertwist-remote-unreal-build.sh | 61 ++- .../__tests__/public-marketing-pages.test.tsx | 6 +- .../windows-package-validation-summary.json | 4 +- 11 files changed, 1155 insertions(+), 20 deletions(-) create mode 100644 docs/generated/browser_automation/Browser-ExactSource-20260630/index.json create mode 100644 scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh diff --git a/docs/generated/browser_automation/Browser-ExactSource-20260630/index.json b/docs/generated/browser_automation/Browser-ExactSource-20260630/index.json new file mode 100644 index 0000000..60bebeb --- /dev/null +++ b/docs/generated/browser_automation/Browser-ExactSource-20260630/index.json @@ -0,0 +1,419 @@ +{ + "devices": [ + { + "deviceName": "DESKTOP-KS3VGHU", + "instance": "1A6ED41B42F9172331469FBD2D852C7C", + "instanceName": "DESKTOP-KS3VGHU-38936", + "platform": "WindowsEditor", + "oSVersion": "Windows 11 (23H2) [10.0.22631.4037] ", + "model": "Default", + "gPU": "GenericGPUBrand", + "cPUModel": "12th Gen Intel(R) Core(TM) i7-12700H", + "rAMInGB": 16, + "renderMode": "SM6", + "rHI": "", + "appInstanceLog": "" + } + ], + "reportCreatedOn": "2026.06.30-10.45.20", + "succeeded": 26, + "succeededWithWarnings": 0, + "failed": 0, + "notRun": 0, + "inProcess": 0, + "totalDuration": 15.698421478271484, + "comparisonExported": false, + "comparisonExportDirectory": "", + "tests": [ + { + "testDisplayName": "NotificationCapture", + "fullTestPath": "HyperTwist.Browser.Bridge.NotificationCapture", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.015972699970006943, + "dateTime": "2026.06.30-10.44.59", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "RuntimeReadyDelegate", + "fullTestPath": "HyperTwist.Browser.Bridge.RuntimeReadyDelegate", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.015567902475595474, + "dateTime": "2026.06.30-10.44.59", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "RuntimeReadyPayloadDecode", + "fullTestPath": "HyperTwist.Browser.Bridge.RuntimeReadyPayloadDecode", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.015711601823568344, + "dateTime": "2026.06.30-10.44.59", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "RuntimeStatusEnvelopeDecode", + "fullTestPath": "HyperTwist.Browser.Bridge.RuntimeStatusEnvelopeDecode", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.016416601836681366, + "dateTime": "2026.06.30-10.44.59", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "TilingStateEnvelopeDecode", + "fullTestPath": "HyperTwist.Browser.Bridge.TilingStateEnvelopeDecode", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.016030300408601761, + "dateTime": "2026.06.30-10.44.59", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlInputReadinessInspectSurface", + "fullTestPath": "HyperTwist.Browser.CoachDashboard.ControlInputReadinessInspectSurface", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.81774640083312988, + "dateTime": "2026.06.30-10.44.59", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlProfileContinuityArtifacts", + "fullTestPath": "HyperTwist.Browser.CoachDashboard.ControlProfileContinuityArtifacts", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 1.1325118541717529, + "dateTime": "2026.06.30-10.45.00", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlProfileRosterInspectSurface", + "fullTestPath": "HyperTwist.Browser.CoachDashboard.ControlProfileRosterInspectSurface", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.49913820624351501, + "dateTime": "2026.06.30-10.45.06", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlSettingsOwnershipInspectSurface", + "fullTestPath": "HyperTwist.Browser.CoachDashboard.ControlSettingsOwnershipInspectSurface", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.86615478992462158, + "dateTime": "2026.06.30-10.45.06", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlSurfaceStructuredTextArtifacts", + "fullTestPath": "HyperTwist.Browser.CoachDashboard.ControlSurfaceStructuredTextArtifacts", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 10.748218536376953, + "dateTime": "2026.06.30-10.45.07", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "RuntimeInspectSurface", + "fullTestPath": "HyperTwist.Browser.CoachDashboard.RuntimeInspectSurface", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.39892959594726562, + "dateTime": "2026.06.30-10.45.18", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlInputReadinessInspectSurface", + "fullTestPath": "HyperTwist.Browser.TrainingPanel.ControlInputReadinessInspectSurface", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.16984249651432037, + "dateTime": "2026.06.30-10.45.18", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlProfileContinuityParity", + "fullTestPath": "HyperTwist.Browser.TrainingPanel.ControlProfileContinuityParity", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.12023679912090302, + "dateTime": "2026.06.30-10.45.19", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlProfileRosterInspectSurface", + "fullTestPath": "HyperTwist.Browser.TrainingPanel.ControlProfileRosterInspectSurface", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.055037502199411392, + "dateTime": "2026.06.30-10.45.19", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlSettingsOwnershipInspectSurface", + "fullTestPath": "HyperTwist.Browser.TrainingPanel.ControlSettingsOwnershipInspectSurface", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.63307029008865356, + "dateTime": "2026.06.30-10.45.19", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "RuntimeInspectSurface", + "fullTestPath": "HyperTwist.Browser.TrainingPanel.RuntimeInspectSurface", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.015922199934720993, + "dateTime": "2026.06.30-10.45.19", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "AuthoritativeShellArtifacts", + "fullTestPath": "HyperTwist.Browser.Widget.AuthoritativeShellArtifacts", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.01653599739074707, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "BundledShellUrl", + "fullTestPath": "HyperTwist.Browser.Widget.BundledShellUrl", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.015801899135112762, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "OperatorStatusSurfaceLive", + "fullTestPath": "HyperTwist.Browser.Widget.OperatorStatusSurfaceLive", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.016534201800823212, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "OperatorStatusSurfaceResetOnShellChange", + "fullTestPath": "HyperTwist.Browser.Widget.OperatorStatusSurfaceResetOnShellChange", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.01616780087351799, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "OperatorStatusSurfaceWaiting", + "fullTestPath": "HyperTwist.Browser.Widget.OperatorStatusSurfaceWaiting", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.01643029972910881, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "QueuedOutboundMessages", + "fullTestPath": "HyperTwist.Browser.Widget.QueuedOutboundMessages", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.015827201306819916, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "StatusSurfaceArtifacts", + "fullTestPath": "HyperTwist.Browser.Widget.StatusSurfaceArtifacts", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.016406100243330002, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlInputContinuityStateFormatting", + "fullTestPath": "HyperTwist.Browser.ControlInputContinuityStateFormatting", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.016290102154016495, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlProfileContinuityStateFormatting", + "fullTestPath": "HyperTwist.Browser.ControlProfileContinuityStateFormatting", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.015774600207805634, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + }, + { + "testDisplayName": "ControlSettingsContinuityStateFormatting", + "fullTestPath": "HyperTwist.Browser.ControlSettingsContinuityStateFormatting", + "tags": [], + "state": "Success", + "deviceInstance": [ + "1A6ED41B42F9172331469FBD2D852C7C" + ], + "duration": 0.016147200018167496, + "dateTime": "2026.06.30-10.45.20", + "entries": [], + "warnings": 0, + "errors": 0, + "artifacts": [] + } + ] +} \ No newline at end of file diff --git a/docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json b/docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json index 1839218..8e46319 100644 --- a/docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json +++ b/docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json @@ -1,8 +1,8 @@ { "reportVersion": "ht-higher-dimensional-package-validation/v1", - "generatedAtUtc": "2026-06-29T14:00:38.8107466Z", - "projectRoot": "C:\\HyperTwist_worktrees\\phase10validate", - "archiveDirectory": "C:\\HyperTwist_worktrees\\phase10validate_packaged_phase6c_higherdim_refresh_20260629", + "generatedAtUtc": "2026-06-30T10:45:24.1772955Z", + "projectRoot": "C:\\HTpp", + "archiveDirectory": "C:\\HTpp_packaged_phase6c_higherdim_refresh_20260630", "configuration": "Development", "cookMaps": [ "/Game/HyperTwistTraining/Maps/L_HyperTwist_Magic120CellTraining", @@ -17,10 +17,10 @@ "-SkipCookingEditorContent" ], "cleanArchive": false, - "skipBuild": true, + "skipBuild": false, "skipLaunch": false, "authoringManifest": { - "path": "C:\\HyperTwist_worktrees\\phase10validate\\docs\\generated\\higher_dimensional_training_maps\\phase6c_dedicated_family_map_manifest.json", + "path": "C:\\HTpp\\docs\\generated\\higher_dimensional_training_maps\\phase6c_dedicated_family_map_manifest.json", "manifestId": "phase6c/dedicated-family-training-map-authoring", "manifestVersion": "2026.06.18", "authoredThroughGameModeClassPath": "/Script/UnrealHyperTwist.HyperTwistCoachDashboardGameMode", @@ -50,13 +50,13 @@ ] }, "result": "passed", - "packagedExecutablePath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_phase6c_higherdim_refresh_20260629\\Windows\\UnrealHyperTwist.exe", + "packagedExecutablePath": "C:\\HTpp_packaged_phase6c_higherdim_refresh_20260630\\Windows\\UnrealHyperTwist.exe", "smokeReports": [ { "reportVersion": "ht-higher-dimensional-package-smoke/v1", - "generatedAtUtc": "2026-06-29T14:01:45.8644849Z", - "packageRoot": "C:\\HyperTwist_worktrees\\phase10validate_packaged_phase6c_higherdim_refresh_20260629", - "executablePath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_phase6c_higherdim_refresh_20260629\\Windows\\UnrealHyperTwist.exe", + "generatedAtUtc": "2026-06-30T11:39:15.0336201Z", + "packageRoot": "C:\\HTpp_packaged_phase6c_higherdim_refresh_20260630", + "executablePath": "C:\\HTpp_packaged_phase6c_higherdim_refresh_20260630\\Windows\\UnrealHyperTwist.exe", "mapUrl": "/Game/HyperTwistTraining/Maps/L_HyperTwist_Magic120CellTraining", "smokeSeconds": 10, "resolution": { @@ -65,16 +65,16 @@ }, "keepRunning": false, "result": "passed", - "processId": 30724, + "processId": 34020, "processStopped": true, "exitCode": null, "error": null }, { "reportVersion": "ht-higher-dimensional-package-smoke/v1", - "generatedAtUtc": "2026-06-29T14:01:56.2411398Z", - "packageRoot": "C:\\HyperTwist_worktrees\\phase10validate_packaged_phase6c_higherdim_refresh_20260629", - "executablePath": "C:\\HyperTwist_worktrees\\phase10validate_packaged_phase6c_higherdim_refresh_20260629\\Windows\\UnrealHyperTwist.exe", + "generatedAtUtc": "2026-06-30T11:39:25.7497608Z", + "packageRoot": "C:\\HTpp_packaged_phase6c_higherdim_refresh_20260630", + "executablePath": "C:\\HTpp_packaged_phase6c_higherdim_refresh_20260630\\Windows\\UnrealHyperTwist.exe", "mapUrl": "/Game/HyperTwistTraining/Maps/L_HyperTwist_MagicCube5DTraining", "smokeSeconds": 10, "resolution": { @@ -83,7 +83,7 @@ }, "keepRunning": false, "result": "passed", - "processId": 34848, + "processId": 34908, "processStopped": true, "exitCode": null, "error": null diff --git a/docs/ops/HYPERTWIST_REVERSE_SSH_WINDOWS_BUILD_LANE_VERIFICATION_2026-06-01.md b/docs/ops/HYPERTWIST_REVERSE_SSH_WINDOWS_BUILD_LANE_VERIFICATION_2026-06-01.md index 35d5a66..ab0c2ae 100644 --- a/docs/ops/HYPERTWIST_REVERSE_SSH_WINDOWS_BUILD_LANE_VERIFICATION_2026-06-01.md +++ b/docs/ops/HYPERTWIST_REVERSE_SSH_WINDOWS_BUILD_LANE_VERIFICATION_2026-06-01.md @@ -183,6 +183,85 @@ The sensitive runbook now carries the exact current Windows-side tunnel commands, known-hosts scratch file, listener verification command, reverse-sync commands, and the still-current password-backed login path. +## Addendum - 2026-06-30 (exact-source fallback refresh and host-lock recovery) + +Live follow-up on `2026-06-30` established these additional facts: + +- the primary reverse-SSH `localhost:22022` lane was still healthy for the + current exact-source browser/package refresh sequence +- the repo now also carries + `scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh` as a + bounded first-party exact-source wrapper that: + - re-proves the remote Windows shell identity + - optionally syncs a bounded set of exact-source browser/package support + files into the target Windows root + - reruns the remote editor build, browser automation, and higher-dimensional + package helper + - pulls the refreshed browser/package evidence back into the tracked repo + - re-renders + `website/src/shared/generated/windows-package-validation-summary.json` +- the maintained validation root remained + `C:\HyperTwist_worktrees\phase10validate`, but the exact-source editor build + on that root failed twice with the same host-side file lock on: + `C:\HyperTwist_worktrees\phase10validate\UnrealHyperTwist\Source\UnrealHyperTwist\Private\HyperTwistTraining\HyperTwistTrainingRepositoryLibrary.cpp` +- `scripts/run-hypertwist-remote-unreal-build.sh` now retries that exact + transient Windows source-lock class once by default before declaring the + build failed, so a host-state file lock is no longer silently conflated with + an ordinary first-pass code failure +- because that maintained-root host lock persisted across the bounded retry, + the same exact-source wrapper truthfully fell back to isolated Windows root + `C:\HTpp` +- that fallback root initially lacked the current `Content\Browser`, package + helper, manifest, and related exact-source support files, so the wrapper + narrow-synced those first instead of pretending the fallback tree was already + exact-source complete +- the fallback root also lacked the packaged-game target receipt + `C:\HTpp\UnrealHyperTwist\Binaries\Win64\UnrealHyperTwist.target`, so the + package helper correctly performed a full packaged build there instead of + forcing `-SkipBuild` +- the same fallback root then passed the current exact-source browser + automation proof through exported report + `docs/generated/browser_automation/Browser-ExactSource-20260630/index.json` + with: + - `26` tests succeeded + - `0` failed + - `0` not run + - `0` in process +- the same fallback root then passed the higher-dimensional package helper + proof with: + - `BuildCookRun` result `passed` + - archive output in + `C:\HTpp_packaged_phase6c_higherdim_refresh_20260630` + - both dedicated-family packaged smoke maps green again: + - `/Game/HyperTwistTraining/Maps/L_HyperTwist_Magic120CellTraining` + - `/Game/HyperTwistTraining/Maps/L_HyperTwist_MagicCube5DTraining` +- the refreshed aggregate package proof was then pulled back into + `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json` + and the public summary was re-rendered into + `website/src/shared/generated/windows-package-validation-summary.json` + with truthful `skip_build: false` +- `scripts/run-hypertwist-remote-unreal-automation.sh` now also treats the + exported automation report itself as authority, not only the + `UnrealEditor-Cmd` process exit: + - it clears any prior report directory first + - requires the new `index.json` to exist + - fails the wrapper when the report records any `failed`, `notRun`, or + `inProcess` counts + +Operational rules reinforced by this proof: + +- when the maintained isolated Windows worktree is temporarily blocked by a + host-side source-file lock, do not falsely report the whole exact-source lane + as green or code-broken until the bounded retry and any declared fallback + lane have both been truthfully exercised +- when a fallback Windows root is used for exact-source browser/package proof, + sync the bounded browser/package support surfaces first instead of assuming a + minimal Unreal tree is already sufficient evidence +- judge remote browser automation success by the exported report counts, not by + process exit alone +- judge higher-dimensional package proof by the real target-receipt posture: + use `-SkipBuild` only when the packaged-game receipt actually exists + ## Addendum - 2026-06-22 (maintained validation-root clarification) Live follow-up on `2026-06-22` established these additional facts: diff --git a/docs/ops/HYPERTWIST_UNREAL_BUILD_VALIDATION_REQUIREMENT_2026-06-01.md b/docs/ops/HYPERTWIST_UNREAL_BUILD_VALIDATION_REQUIREMENT_2026-06-01.md index ad2a00a..880a33b 100644 --- a/docs/ops/HYPERTWIST_UNREAL_BUILD_VALIDATION_REQUIREMENT_2026-06-01.md +++ b/docs/ops/HYPERTWIST_UNREAL_BUILD_VALIDATION_REQUIREMENT_2026-06-01.md @@ -236,6 +236,30 @@ This extends the doctrine from a one-off helper proof into a re-proven maintained package lane that still stays green after later editor-build recovery work on the same primary reverse-SSH path. +Further exact-source browser/package refresh proof on `2026-06-30` then +extended that same doctrine into truthful fallback-root recovery when the +maintained isolated Windows worktree was temporarily blocked by host state: +the current primary lane on `localhost:22022` still accepted the session, but +the maintained validation root `C:\HyperTwist_worktrees\phase10validate` +failed its exact-source editor rebuild twice because +`HyperTwistTrainingRepositoryLibrary.cpp` was held by another Windows process. +The new bounded wrapper +`scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh` then +fell back to isolated root `C:\HTpp`, narrow-synced the exact-source +browser/package support files that that fallback root lacked, rebuilt the +editor there successfully, reran `HyperTwist.Browser` automation with pulled +report `docs/generated/browser_automation/Browser-ExactSource-20260630/index.json` +showing `26` succeeded, `0` failed, `0` not run, and `0` in process, then +performed a truthful full higher-dimensional package build because the fallback +root had no packaged-game target receipt. The refreshed aggregate package +proof still passed, both dedicated-family packaged smoke maps stayed green, and +the checked-in public summary at +`website/src/shared/generated/windows-package-validation-summary.json` was +re-rendered with `skip_build: false`. This extends the doctrine from +maintained-root `-SkipBuild` helper proof into bounded exact-source fallback +proof when a live Windows host lock temporarily makes the maintained root +unusable. + Further `2026-06-13` continuation proof on that same primary lane recovered the classic-cube replay/leaderboard/package slice after a corrupted reverse sync incident: a prior aborted broad tar sync left remote diff --git a/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md b/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md index 4fdc1c6..9f17ffc 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/DEVELOPMENT.md @@ -191,6 +191,18 @@ Current packaged-proof bridge truth after the same `2026-06-23` continuation: bounded first-party way to pull Windows-side validation artifacts back into the HyperTwist repo with explicit remote-to-local path mapping and SHA-256 verification instead of relying on ad hoc manual copies +- `scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh` now + gives the lane one bounded exact-source browser/package recovery entry point: + - it can re-prove the remote shell identity, sync the exact-source + browser/package support files a fallback root needs, rerun the editor + build plus `HyperTwist.Browser` automation plus the higher-dimensional + package helper, pull the refreshed evidence back into the tracked repo, and + re-render the public Windows packaged-proof summary in one same-family pass + - the wrapper only claims browser automation success when the exported + automation report itself exists and records `0` failed, `0` not run, and + `0` in-process tests + - the wrapper only claims higher-dimensional `-SkipBuild` package proof when + the packaged-game target receipt actually exists on the chosen Windows root Current bounded refactor-tool truth after the `2026-06-24` follow-up: @@ -2449,10 +2461,111 @@ Latest same-family responsive public-route expansion follow-up on `2026-06-29`: - deployment/readiness tooling validation: - `3` files passed - `30` tests passed + - `website/server` validation: + - `10` files passed + - `36` tests passed + - website plus `Content/Browser` production builds passed + +## Exact-source fallback refresh plus owned web-surface recovery (`2026-06-30`) + +- the next bounded continuation stayed on the already-open production- + hardening and public/manual authority lane and did not widen product scope +- the primary reverse-SSH `localhost:22022` lane was re-proved first and + remained healthy for the current exact-source refresh +- the repo now carries one bounded exact-source recovery wrapper: + - `scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh` +- the maintained validation root still remained: + - `C:\HyperTwist_worktrees\phase10validate` +- the current exact-source editor rebuild on that maintained root then failed + twice because Windows still held: + - `UnrealHyperTwist\Source\UnrealHyperTwist\Private\HyperTwistTraining\HyperTwistTrainingRepositoryLibrary.cpp` + open from another process +- the remote build wrapper now treats that specific source-lock class as a + bounded retry case: + - `scripts/run-hypertwist-remote-unreal-build.sh` + - one default retry + - `3` second retry delay +- because that host-state lock persisted across the bounded retry, the exact- + source recovery wrapper then truthfully fell back to: + - `C:\HTpp` +- that fallback root was not exact-source-complete on its own, so the wrapper + narrow-synced the current browser/package support surfaces first: + - `Content/Browser/index.html` + - `Content/Browser/src/browser-runtime-bootstrap.js` + - `Content/Browser/src/browser-spatial-runtime-fallback.js` + - `Content/Browser/src/runtime/shell.ts` + - `scripts/Invoke-HyperTwistHigherDimensionalPackage.ps1` + - `scripts/Launch-HyperTwistHigherDimensionalPackage.ps1` + - `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_map_manifest.json` +- the fallback root then rebuilt the editor successfully and reran the current + browser authority proof through: + - `scripts/run-hypertwist-remote-unreal-automation.sh --filter HyperTwist.Browser --report-name Browser-ExactSource-20260630` + - pulled report: + `docs/generated/browser_automation/Browser-ExactSource-20260630/index.json` + - result: + - `26` tests succeeded + - `0` failed + - `0` not run + - `0` in process +- `scripts/run-hypertwist-remote-unreal-automation.sh` is now stricter and + more truthful for future sessions: + - it removes any stale report directory before the run + - requires the new `index.json` export to exist + - fails when the exported report itself records `failed`, `notRun`, or + `inProcess` counts even if `UnrealEditor-Cmd` exited `0` +- the higher-dimensional package helper then ran from the same fallback exact- + source state, but this time the lane correctly detected that + `C:\HTpp\UnrealHyperTwist\Binaries\Win64\UnrealHyperTwist.target` was absent + there, so it did a truthful full package build instead of forcing + `-SkipBuild` +- the refreshed higher-dimensional package proof then stayed green: + - `BuildCookRun` result `passed` + - archive: + `C:\HTpp_packaged_phase6c_higherdim_refresh_20260630` + - both dedicated-family packaged smoke maps passed again: + - `Magic120Cell` + - `MagicCube5D` + - refreshed aggregate report: + `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json` +- the public packaged-proof bridge was then rerendered from that exact-source + package report again: + - `website/src/shared/generated/windows-package-validation-summary.json` + - truthful posture now shows `skip_build: false` +- the related public marketing proof was hardened so website tests accept the + two truthful packaged-build modes instead of assuming only one: + - existing target receipt reused + - full package build +- the same repo state then reran the full owned web-surface gate green: + - `scripts/run-hypertwist-web-surface-validation.sh` + - focused website route/auth/release validation: + - `14` files passed + - `84` tests passed + - deployment/readiness tooling validation: + - `4` files passed + - `34` tests passed - `website/server` validation: - `10` files passed - `36` tests passed - website plus `Content/Browser` production builds passed + - website production audit stayed at: + - `found 0 vulnerabilities` + - `Content/Browser` production audit stayed at: + - `found 0 vulnerabilities` + - the same already-documented upstream auth-server residual remained the + only accepted production-audit note: + - `supertokens-node -> nodemailer` +- the HyperTwist-owned structural and analysis loop also stayed healthy on the + same current state: + - `scripts/run-hypertwist-sentrux-source-only.sh` + - `Quality: 6245` + - all `7` rules passing + - `scripts/run-hypertwist-gitnexus-analyze.sh` + - the repo-owned local CLI still exhibits the current post-index + `free(): invalid pointer` quirk on this Linux host + - the wrapper now treats that exact post-index case as success after a fresh + follow-up `status` confirms the bounded mirror is current + - `scripts/run-hypertwist-gitnexus-status.sh` + - bounded mirror `Status: up-to-date` - `website/` and `Content/Browser/` production audits stayed at `found 0 vulnerabilities` - `website/server/` again retained only the same already-documented upstream 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 94fd7eb..be828c2 100644 --- a/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md +++ b/docs/v6_5_deep_manual_pack/HyperTwist/FEATURE_REGISTRY.md @@ -294,7 +294,7 @@ repo. | Higher-dimensional initial shared-map launch and view-context execution bridge | Implemented now | landed `Phase 6C` continuation packet | First-party current code first bundled higher-dimensional launch surfaces and view-context surfaces for `Magic120Cell` and `MagicCube5D`, resolved those surfaces through the training runtime library plus the live training panel/session-actor caches, and let the training subsystem start the shared-map seed run, apply default selector posture, persist the generated-mode launch request, and start the owned generated run without widening into external-process ownership. After recovering an interrupted follow-up, the primary reverse-SSH `localhost:22022` Windows lane rebuilt that cleaned slice on `2026-06-18` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 124.81 seconds`, and passed all `8` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including `LaunchCatalog`, `ViewContextCatalog`, `LaunchExecution`, and `RunStateActivationResolution`; that initial bridge is now superseded by the later dedicated-family map ownership continuation. | | Higher-dimensional explicit dedicated-host seam | Implemented now | landed `Phase 6C` host-surface continuation packet | First-party current code then recorded the preferred dedicated-family `Magic120Cell` / `MagicCube5D` host-map targets in an explicit higher-dimensional host-surface catalog while the slice still kept the shared training map as the interim effective runtime fallback, mirrored that resolved host seam through the training runtime library plus the panel/session caches, and threaded the host-surface id into the launch/view-context surfaces and generated-mode lineage. The primary reverse-SSH `localhost:22022` Windows lane rebuilt this widened slice on `2026-06-18` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 2858.02 seconds`, and passed all `9` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including the new `HostCatalog`; that interim fallback is now superseded by the later dedicated-family map ownership continuation. | | Higher-dimensional executed runtime session surface | Implemented now | landed `Phase 6C` session-surface continuation packet | First-party current code now merges the higher-dimensional launch, host, and view-context seams into an explicit runtime-session catalog for `Magic120Cell` and `MagicCube5D`, mirrors that session surface through the training runtime library plus the panel/session caches, upgrades generated-mode deck lineage to record the resolved session surface, and applies the merged launch-plus-view selector posture at start time instead of only the narrower launch defaults. The primary reverse-SSH `localhost:22022` Windows lane rebuilt this widened slice on `2026-06-18` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 3541.98 seconds`, and passed all `10` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests, including the new `SessionCatalog`; the longer `LaunchExecution` quiet interval of `573.84 seconds` remained known-good. | -| Higher-dimensional dedicated-family interactive scene ownership | Implemented now | landed `Phase 6C` interactive-scene and dedicated-host continuation packet | First-party current code now promotes the higher-dimensional runtime-session seams into explicit `Magic120Cell` and `MagicCube5D` interactive-scene surfaces with family-owned runtime-state, projection, and persistence envelopes, replaces the shared-map bridge with dedicated-family training-map assets plus dedicated host/launch/view-context/session surfaces, exposes explicit scene-envelope decoders through the runtime library, batches default selector application so generated-mode launch execution no longer rebuilds repository views once per selector, and then defers repository-view projection across the internal generated-mode handoff itself so only the final launch state forces a view refresh. The primary reverse-SSH `localhost:22022` Windows lane rebuilt the dedicated-family ownership slice on `2026-06-18` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 1648.33 seconds`; the later projection-deferral hardening rebuild completed in `400.77 seconds`, and the exported automation report passed all `11` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests with `totalDuration` `41.88494873046875`, `LaunchExecution` duration `41.53509521484375`, and the controller quiet interval reduced to `41.52 seconds`. The current recovery-proof continuation now also deterministically reauthors the dedicated-family maps through `scripts/hypertwist_author_higher_dimensional_training_maps.py`, records manifest-backed owned hashes in `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_map_manifest.json`, preserves the optional `AHyperTwistHigherDimensionalTrainingShellActor` for manual/editor authoring while intentionally skipping it on the headless commandlet lane because that spawn path still crashes `UnrealEditor-Cmd`, passes all `13` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests through pulled proof in `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_map_ownership_automation_report.json`, including `DedicatedMapAuthoringManifest` and `DedicatedMapOwnedShell`, and now has a maintained packaged-validation seam through `scripts/Invoke-HyperTwistHigherDimensionalPackage.ps1` plus `scripts/Launch-HyperTwistHigherDimensionalPackage.ps1`. That helper was then live-validated on `2026-06-22` against isolated worktree `C:\HyperTwist_worktrees\phase10validate` in `-SkipBuild` mode, with `BuildCookRun time: 118.53 s`, archive output in `C:\HyperTwist_worktrees\phase10validate_packaged_phase6c_higherdim`, both dedicated-family packaged smoke maps green, and pulled aggregate proof in `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json`. The same maintained helper lane was refreshed again on `2026-06-23` after the recovered authoritative editor rebuild, again in `-SkipBuild` mode against the existing receipt, with `BuildCookRun time: 70.74 s`, archive output in `C:\HyperTwist_worktrees\phase10validate_packaged_phase6c_higherdim_refresh_20260623`, both dedicated-family packaged smoke maps green again, and the checked-in aggregate report refreshed in place. | +| Higher-dimensional dedicated-family interactive scene ownership | Implemented now | landed `Phase 6C` interactive-scene and dedicated-host continuation packet | First-party current code now promotes the higher-dimensional runtime-session seams into explicit `Magic120Cell` and `MagicCube5D` interactive-scene surfaces with family-owned runtime-state, projection, and persistence envelopes, replaces the shared-map bridge with dedicated-family training-map assets plus dedicated host/launch/view-context/session surfaces, exposes explicit scene-envelope decoders through the runtime library, batches default selector application so generated-mode launch execution no longer rebuilds repository views once per selector, and then defers repository-view projection across the internal generated-mode handoff itself so only the final launch state forces a view refresh. The primary reverse-SSH `localhost:22022` Windows lane rebuilt the dedicated-family ownership slice on `2026-06-18` with `Result: Succeeded`, UnrealBuildTool `Total execution time: 1648.33 seconds`; the later projection-deferral hardening rebuild completed in `400.77 seconds`, and the exported automation report passed all `11` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests with `totalDuration` `41.88494873046875`, `LaunchExecution` duration `41.53509521484375`, and the controller quiet interval reduced to `41.52 seconds`. The current recovery-proof continuation now also deterministically reauthors the dedicated-family maps through `scripts/hypertwist_author_higher_dimensional_training_maps.py`, records manifest-backed owned hashes in `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_map_manifest.json`, preserves the optional `AHyperTwistHigherDimensionalTrainingShellActor` for manual/editor authoring while intentionally skipping it on the headless commandlet lane because that spawn path still crashes `UnrealEditor-Cmd`, passes all `13` `HyperTwist.FirstParty.HigherDimensional.Phase6C` tests through pulled proof in `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_map_ownership_automation_report.json`, including `DedicatedMapAuthoringManifest` and `DedicatedMapOwnedShell`, and now has a maintained packaged-validation seam through `scripts/Invoke-HyperTwistHigherDimensionalPackage.ps1` plus `scripts/Launch-HyperTwistHigherDimensionalPackage.ps1`. That helper was then live-validated on `2026-06-22` against isolated worktree `C:\HyperTwist_worktrees\phase10validate` in `-SkipBuild` mode, with `BuildCookRun time: 118.53 s`, archive output in `C:\HyperTwist_worktrees\phase10validate_packaged_phase6c_higherdim`, both dedicated-family packaged smoke maps green, and pulled aggregate proof in `docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json`. The same maintained helper lane was refreshed again on `2026-06-23` after the recovered authoritative editor rebuild, again in `-SkipBuild` mode against the existing receipt, with `BuildCookRun time: 70.74 s`, archive output in `C:\HyperTwist_worktrees\phase10validate_packaged_phase6c_higherdim_refresh_20260623`, both dedicated-family packaged smoke maps green again, and the checked-in aggregate report refreshed in place. A later exact-source recovery on `2026-06-30` then proved the same dedicated-family package lane can stay truthful even when the maintained isolated worktree is temporarily blocked by a Windows host file lock: the new bounded wrapper `scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh` retried the maintained-root editor build, fell back to `C:\HTpp` when the lock persisted, narrow-synced the exact-source browser/package support surfaces that fallback root lacked, reran `HyperTwist.Browser` proof with `26` succeeded and `0` failed, then completed a full packaged higher-dimensional build there because the fallback root did not yet have the packaged-game target receipt. Both dedicated-family smoke maps still passed, and the checked-in aggregate package report plus public summary were refreshed with truthful `skip_build: false` posture instead of pretending the old maintained-root `-SkipBuild` condition still applied. | | Broad non-Euclidean interaction shell and host ownership | Deep-source grounded retained | `MagicTile` retained remainder | Broad interaction-shell, WinForms/OpenTK host ownership, native spherical/hyperbolic renderer ownership beyond the landed first-party native behavior proof, and generic runtime replacement remain deferred after the landed `Phase 6R-T`, `Phase 7A`, `Phase 7B`, and `Phase 7C` slices, with later native renderer reopening now governed by the separate spec-only `Phase 7D` decision gate. | ### 8. Speech input and voice sidecars diff --git a/scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh b/scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh new file mode 100644 index 0000000..f1a0f58 --- /dev/null +++ b/scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh @@ -0,0 +1,412 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat <<'EOF' +Usage: + HYPERTWIST_REMOTE_WINDOWS_PASSWORD=... \ + scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh + +Options: + --worktree-root + Optional Windows worktree root. Defaults to C:\HyperTwist_worktrees\phase10validate. + + --report-stamp + Optional suffix used for the browser automation report and package archive. + Defaults to the current UTC date. + + --fallback-worktree-root + Optional fallback Windows worktree root to use if the primary refresh + fails. Useful when the maintained worktree is temporarily locked by + another Windows-side process. + + --browser-filter + Optional Unreal automation filter. Defaults to HyperTwist.Browser. + + --browser-report-name + Optional explicit browser automation report name. Defaults to + Browser-ExactSource-. + + --package-archive-dir + Optional Windows archive directory for the higher-dimensional package run. + Defaults to _packaged_phase6c_higherdim_refresh_. + + --sync-file + Optional repo-relative file to sync into the remote Windows worktree before + validation. May be repeated. + + --skip-build + Skip the remote Unreal editor build step. + + --skip-browser-automation + Skip the HyperTwist.Browser automation refresh. + + --skip-package + Skip the higher-dimensional package refresh. + + --skip-browser-report-pull + Skip pulling the browser automation index.json back into docs/generated. + + --skip-package-report-pull + Skip pulling the higher-dimensional package validation report back into + docs/generated. + + --skip-summary-refresh + Skip re-rendering website/src/shared/generated/windows-package-validation-summary.json. + + --skip-exact-source-support-sync + Skip syncing the bounded exact-source browser/package support files that + the fallback Windows validation root needs for truthful browser/package + refreshes. + + --dry-run + Print the wrapper invocations without executing them. + +Environment: + HYPERTWIST_REMOTE_WINDOWS_PASSWORD Required by the underlying remote wrappers. + HYPERTWIST_REMOTE_WINDOWS_WORKTREE_ROOT Optional default for --worktree-root. + HYPERTWIST_REMOTE_WINDOWS_FALLBACK_WORKTREE_ROOT + Optional default for --fallback-worktree-root. + HYPERTWIST_REMOTE_WINDOWS_SKIP_EXACT_SOURCE_SUPPORT_SYNC + Optional default for --skip-exact-source-support-sync. +EOF +} + +ps_single_quote() { + printf "'%s'" "${1//\'/\'\'}" +} + +run_or_print() { + if [[ "$dry_run" == "true" ]]; then + printf '%q ' "$@" + printf '\n' + return 0 + fi + + "$@" +} + +worktree_root="${HYPERTWIST_REMOTE_WINDOWS_WORKTREE_ROOT:-C:\\HyperTwist_worktrees\\phase10validate}" +fallback_worktree_root="${HYPERTWIST_REMOTE_WINDOWS_FALLBACK_WORKTREE_ROOT:-}" +report_stamp="$(date -u '+%Y%m%d')" +browser_filter="HyperTwist.Browser" +browser_report_name="" +package_archive_dir="" +sync_files=() +skip_build="false" +skip_browser_automation="false" +skip_package="false" +skip_browser_report_pull="false" +skip_package_report_pull="false" +skip_summary_refresh="false" +skip_exact_source_support_sync="${HYPERTWIST_REMOTE_WINDOWS_SKIP_EXACT_SOURCE_SUPPORT_SYNC:-false}" +dry_run="false" + +while [[ $# -gt 0 ]]; do + case "$1" in + --worktree-root) + worktree_root="${2:-}" + shift 2 + ;; + --report-stamp) + report_stamp="${2:-}" + shift 2 + ;; + --fallback-worktree-root) + fallback_worktree_root="${2:-}" + shift 2 + ;; + --browser-filter) + browser_filter="${2:-}" + shift 2 + ;; + --browser-report-name) + browser_report_name="${2:-}" + shift 2 + ;; + --package-archive-dir) + package_archive_dir="${2:-}" + shift 2 + ;; + --sync-file) + sync_files+=("${2:-}") + shift 2 + ;; + --skip-build) + skip_build="true" + shift + ;; + --skip-browser-automation) + skip_browser_automation="true" + shift + ;; + --skip-package) + skip_package="true" + shift + ;; + --skip-browser-report-pull) + skip_browser_report_pull="true" + shift + ;; + --skip-package-report-pull) + skip_package_report_pull="true" + shift + ;; + --skip-summary-refresh) + skip_summary_refresh="true" + shift + ;; + --skip-exact-source-support-sync) + skip_exact_source_support_sync="true" + shift + ;; + --dry-run) + dry_run="true" + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + usage >&2 + exit 1 + ;; + esac +done + +if [[ -z "$browser_report_name" ]]; then + browser_report_name="Browser-ExactSource-${report_stamp}" +fi + +if [[ -z "$package_archive_dir" ]]; then + package_archive_dir="${worktree_root}_packaged_phase6c_higherdim_refresh_${report_stamp}" +fi + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +repo_root="$(cd "${script_dir}/.." && pwd)" +remote_ps_wrapper="${script_dir}/run-hypertwist-remote-windows-powershell.sh" +remote_build_wrapper="${script_dir}/run-hypertwist-remote-unreal-build.sh" +remote_automation_wrapper="${script_dir}/run-hypertwist-remote-unreal-automation.sh" +remote_sync_wrapper="${script_dir}/run-hypertwist-remote-windows-file-sync.sh" +remote_pull_wrapper="${script_dir}/run-hypertwist-remote-windows-file-pull.sh" +summary_refresh_script="${script_dir}/render-hypertwist-web-package-validation-summary.mjs" + +for required_wrapper in \ + "$remote_ps_wrapper" \ + "$remote_build_wrapper" \ + "$remote_automation_wrapper" \ + "$remote_sync_wrapper" \ + "$remote_pull_wrapper" +do + if [[ ! -x "$required_wrapper" ]]; then + echo "Expected executable wrapper at $required_wrapper" >&2 + exit 1 + fi +done + +if [[ ! -f "$summary_refresh_script" ]]; then + echo "Expected summary refresh script at $summary_refresh_script" >&2 + exit 1 +fi + +if [[ -z "${HYPERTWIST_REMOTE_WINDOWS_PASSWORD:-}" ]]; then + echo "Set HYPERTWIST_REMOTE_WINDOWS_PASSWORD before running this refresh." >&2 + exit 1 +fi + +host_probe_command="Write-Output ('USER=' + [System.Security.Principal.WindowsIdentity]::GetCurrent().Name); Write-Output ('HOST=' + \$env:COMPUTERNAME)" +browser_report_local_path="docs/generated/browser_automation/${browser_report_name}/index.json" +package_report_local_path="docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json" +exact_source_support_files=( + "Content/Browser/index.html" + "Content/Browser/src/browser-runtime-bootstrap.js" + "Content/Browser/src/browser-spatial-runtime-fallback.js" + "Content/Browser/src/runtime/shell.ts" + "scripts/Invoke-HyperTwistHigherDimensionalPackage.ps1" + "scripts/Launch-HyperTwistHigherDimensionalPackage.ps1" + "docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_map_manifest.json" +) +effective_sync_files=() + +add_effective_sync_file() { + local candidate="$1" + local existing + for existing in "${effective_sync_files[@]}"; do + if [[ "$existing" == "$candidate" ]]; then + return 0 + fi + done + effective_sync_files+=("$candidate") +} + +if [[ "$skip_exact_source_support_sync" != "true" ]]; then + for sync_file in "${exact_source_support_files[@]}"; do + add_effective_sync_file "$sync_file" + done +fi + +for sync_file in "${sync_files[@]}"; do + add_effective_sync_file "$sync_file" +done + +run_refresh_for_root() { + local current_worktree_root="$1" + local current_validation_report_path="${current_worktree_root}\\docs\\generated\\higher_dimensional_training_maps\\phase6c_dedicated_family_package_validation_report.json" + local browser_report_remote_path="${current_worktree_root}\\UnrealHyperTwist\\Saved\\AutomationReports\\${browser_report_name}\\index.json" + local package_report_remote_path="$current_validation_report_path" + local current_package_script_path="${current_worktree_root}\\scripts\\Invoke-HyperTwistHigherDimensionalPackage.ps1" + local current_package_archive_dir="$package_archive_dir" + local current_game_target_receipt_path="${current_worktree_root}\\UnrealHyperTwist\\Binaries\\Win64\\UnrealHyperTwist.target" + local package_skip_build_clause="" + local step_exit=0 + + if [[ "$current_worktree_root" != "$worktree_root" && "$package_archive_dir" == "${worktree_root}_packaged_phase6c_higherdim_refresh_${report_stamp}" ]]; then + current_package_archive_dir="${current_worktree_root}_packaged_phase6c_higherdim_refresh_${report_stamp}" + fi + + echo "Re-proving remote Windows lane through ${current_worktree_root}." + if run_or_print "$remote_ps_wrapper" --command "$host_probe_command"; then + : + else + step_exit="$?" + return "$step_exit" + fi + + if [[ ${#effective_sync_files[@]} -gt 0 ]]; then + echo "Syncing ${#effective_sync_files[@]} repo-relative exact-source support file(s) into ${current_worktree_root}." + local sync_command=("$remote_sync_wrapper") + local sync_file + for sync_file in "${effective_sync_files[@]}"; do + sync_command+=(--file "$sync_file") + done + sync_command+=(--remote-root "$current_worktree_root") + if run_or_print "${sync_command[@]}"; then + : + else + step_exit="$?" + return "$step_exit" + fi + fi + + if [[ "$skip_build" != "true" ]]; then + echo "Running remote Unreal editor build." + if run_or_print "$remote_build_wrapper" --worktree-root "$current_worktree_root"; then + : + else + step_exit="$?" + return "$step_exit" + fi + fi + + if [[ "$skip_browser_automation" != "true" ]]; then + echo "Running remote browser automation refresh (~10-20s once the editor lane is warm)." + if run_or_print \ + env HYPERTWIST_REMOTE_WINDOWS_WORKTREE_ROOT="$current_worktree_root" \ + "$remote_automation_wrapper" \ + --filter "$browser_filter" \ + --report-name "$browser_report_name" + then + : + else + step_exit="$?" + return "$step_exit" + fi + fi + + if [[ "$skip_package" != "true" ]]; then + echo "Running remote higher-dimensional package refresh (~1-3m on the maintained lane)." + if [[ "$dry_run" == "true" ]]; then + echo "Dry run: package helper would auto-detect whether ${current_game_target_receipt_path} exists before deciding on -SkipBuild." + else + local package_skip_build_probe_output + if package_skip_build_probe_output="$( + "$remote_ps_wrapper" --command "\$GameTargetReceiptPath = $(ps_single_quote "$current_game_target_receipt_path"); Write-Output ('PACKAGE_SKIP_BUILD=' + (Test-Path -LiteralPath \$GameTargetReceiptPath).ToString().ToLowerInvariant())" \ + | tr -d '\r' + )"; then + : + else + step_exit="$?" + return "$step_exit" + fi + if printf '%s\n' "$package_skip_build_probe_output" | grep -Fq 'PACKAGE_SKIP_BUILD=true'; then + package_skip_build_clause=" -SkipBuild" + echo "Package helper will reuse the existing Win64 game target receipt." + else + echo "Package helper will rebuild the Win64 game target because the packaged-game receipt is absent." + fi + fi + local package_command + package_command="$( + cat <&2 + run_refresh_for_root "$fallback_worktree_root" + active_worktree_root="$fallback_worktree_root" + else + exit "$primary_exit" + fi +fi + +echo "Remote exact-source browser/package refresh complete through ${active_worktree_root}." diff --git a/scripts/run-hypertwist-remote-unreal-automation.sh b/scripts/run-hypertwist-remote-unreal-automation.sh index 662ec49..5e25404 100644 --- a/scripts/run-hypertwist-remote-unreal-automation.sh +++ b/scripts/run-hypertwist-remote-unreal-automation.sh @@ -113,7 +113,11 @@ lines = [ f"$ReportExportPath = {ps_single_quote(report_export_path)}", f"$AbsLogPath = {ps_single_quote(abs_log_path)}", f"$Filter = {ps_single_quote(filter_name)}", + "$ReportIndexPath = Join-Path $ReportExportPath 'index.json'", "", + "if (Test-Path -LiteralPath $ReportExportPath) {", + " Remove-Item -LiteralPath $ReportExportPath -Recurse -Force", + "}", "New-Item -ItemType Directory -Force -Path $ReportExportPath | Out-Null", "New-Item -ItemType Directory -Force -Path (Split-Path -Parent $AbsLogPath) | Out-Null", "", @@ -146,7 +150,28 @@ if extra_args: lines.extend([ " \"-TestExit=Automation Test Queue Empty\"", "", - "exit $LASTEXITCODE", + "$EditorExitCode = $LASTEXITCODE", + "if ($EditorExitCode -ne 0) {", + " exit $EditorExitCode", + "}", + "", + "if (-not (Test-Path -LiteralPath $ReportIndexPath)) {", + " throw \"Automation report index was not written to '$ReportIndexPath'.\"", + "}", + "", + "$Report = Get-Content -LiteralPath $ReportIndexPath -Raw | ConvertFrom-Json", + "if ($null -eq $Report) {", + " throw \"Automation report '$ReportIndexPath' could not be parsed.\"", + "}", + "", + "$FailedCount = if ($null -ne $Report.failed) { [int]$Report.failed } else { 0 }", + "$NotRunCount = if ($null -ne $Report.notRun) { [int]$Report.notRun } else { 0 }", + "$InProcessCount = if ($null -ne $Report.inProcess) { [int]$Report.inProcess } else { 0 }", + "if ($FailedCount -gt 0 -or $NotRunCount -gt 0 -or $InProcessCount -gt 0) {", + " throw \"Automation report '$ReportIndexPath' recorded failed=$FailedCount notRun=$NotRunCount inProcess=$InProcessCount for filter '$Filter'.\"", + "}", + "", + "exit 0", ]) print("\n".join(lines)) diff --git a/scripts/run-hypertwist-remote-unreal-build.sh b/scripts/run-hypertwist-remote-unreal-build.sh index 0af415c..4c7ba7b 100644 --- a/scripts/run-hypertwist-remote-unreal-build.sh +++ b/scripts/run-hypertwist-remote-unreal-build.sh @@ -32,6 +32,13 @@ Options: --allow-uba Allow UBA instead of forcing the verified remote-lane -NoUBA posture. + --source-lock-retries + Retry the remote build when UnrealBuildTool hits a transient Windows + source-file lock. Defaults to 1. + + --source-lock-retry-delay-seconds + Delay between transient source-lock retries. Defaults to 3 seconds. + --extra-arg Append an extra Build.bat argument. May be repeated. @@ -45,6 +52,10 @@ Environment: HYPERTWIST_REMOTE_WINDOWS_BUILD_BAT Optional default for --build-batch-path. HYPERTWIST_REMOTE_WINDOWS_MAX_PARALLEL_ACTIONS Optional default for --max-parallel-actions. + HYPERTWIST_REMOTE_WINDOWS_SOURCE_LOCK_RETRIES + Optional default for --source-lock-retries. + HYPERTWIST_REMOTE_WINDOWS_SOURCE_LOCK_RETRY_DELAY_SECONDS + Optional default for --source-lock-retry-delay-seconds. EOF } @@ -55,6 +66,8 @@ worktree_root="${HYPERTWIST_REMOTE_WINDOWS_WORKTREE_ROOT:-C:\\HyperTwist_worktre project_path="" build_batch_path="${HYPERTWIST_REMOTE_WINDOWS_BUILD_BAT:-C:\\Program Files\\Epic Games\\UE_5.7\\Engine\\Build\\BatchFiles\\Build.bat}" max_parallel_actions="${HYPERTWIST_REMOTE_WINDOWS_MAX_PARALLEL_ACTIONS:-2}" +source_lock_retries="${HYPERTWIST_REMOTE_WINDOWS_SOURCE_LOCK_RETRIES:-1}" +source_lock_retry_delay_seconds="${HYPERTWIST_REMOTE_WINDOWS_SOURCE_LOCK_RETRY_DELAY_SECONDS:-3}" allow_uba="false" dry_run="false" extra_args=() @@ -93,6 +106,14 @@ while [[ $# -gt 0 ]]; do allow_uba="true" shift ;; + --source-lock-retries) + source_lock_retries="${2:-}" + shift 2 + ;; + --source-lock-retry-delay-seconds) + source_lock_retry_delay_seconds="${2:-}" + shift 2 + ;; --extra-arg) extra_args+=("${2:-}") shift 2 @@ -126,6 +147,16 @@ if [[ -n "$max_parallel_actions" && ! "$max_parallel_actions" =~ ^[0-9]+$ ]]; th exit 1 fi +if [[ -n "$source_lock_retries" && ! "$source_lock_retries" =~ ^[0-9]+$ ]]; then + echo "--source-lock-retries must be numeric." >&2 + exit 1 +fi + +if [[ -n "$source_lock_retry_delay_seconds" && ! "$source_lock_retry_delay_seconds" =~ ^[0-9]+$ ]]; then + echo "--source-lock-retry-delay-seconds must be numeric." >&2 + exit 1 +fi + script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" remote_ps_wrapper="${script_dir}/run-hypertwist-remote-windows-powershell.sh" @@ -210,4 +241,32 @@ if [[ "$dry_run" == "true" ]]; then exit 0 fi -exec "$remote_ps_wrapper" --command "$powershell_payload" +source_lock_marker="because it is being used by another process" +attempt=1 +max_attempts=$((source_lock_retries + 1)) +build_output_path="$(mktemp)" +trap 'rm -f "$build_output_path"' EXIT + +while :; do + set +e + "$remote_ps_wrapper" --command "$powershell_payload" 2>&1 | tee "$build_output_path" + build_exit="${PIPESTATUS[0]}" + set -e + + if [[ "$build_exit" -eq 0 ]]; then + exit 0 + fi + + if ! grep -Fq "$source_lock_marker" "$build_output_path"; then + exit "$build_exit" + fi + + if (( attempt >= max_attempts )); then + echo "Remote Unreal build exhausted ${max_attempts} attempt(s) after transient source-file lock detection." >&2 + exit "$build_exit" + fi + + attempt=$((attempt + 1)) + echo "Retrying remote Unreal build after transient source-file lock (${attempt}/${max_attempts}) in ${source_lock_retry_delay_seconds}s..." >&2 + sleep "$source_lock_retry_delay_seconds" +done diff --git a/website/src/__tests__/public-marketing-pages.test.tsx b/website/src/__tests__/public-marketing-pages.test.tsx index 099378f..ffa16e3 100644 --- a/website/src/__tests__/public-marketing-pages.test.tsx +++ b/website/src/__tests__/public-marketing-pages.test.tsx @@ -1172,7 +1172,11 @@ describe('public marketing pages', () => { expect(within(packagedProofSection as HTMLElement).getByText('Packaged validation passed')).toBeTruthy() expect(within(packagedProofSection as HTMLElement).getByText(/The Windows lane has current first-party package proof/i)).toBeTruthy() expect(within(packagedProofSection as HTMLElement).getByText(/MagicCube5D dedicated-family training map: passed/i)).toBeTruthy() - expect(within(packagedProofSection as HTMLElement).getByText(/Build step during latest proof: skipped and reused existing target receipt/i)).toBeTruthy() + expect( + within(packagedProofSection as HTMLElement).getByText( + /Build step during latest proof: (skipped and reused existing target receipt|full package build)/i + ) + ).toBeTruthy() expect(screen.getAllByText('Support topic quick routes').length).toBeGreaterThan(0) expect(screen.getByText('Choose the right HyperTwist surface')).toBeTruthy() expect(screen.getByText('Why HyperTwist keeps both a website and a desktop runtime')).toBeTruthy() diff --git a/website/src/shared/generated/windows-package-validation-summary.json b/website/src/shared/generated/windows-package-validation-summary.json index 1e88c78..9ea6128 100644 --- a/website/src/shared/generated/windows-package-validation-summary.json +++ b/website/src/shared/generated/windows-package-validation-summary.json @@ -1,9 +1,9 @@ { "lane": "Windows Unreal packaged validation", "result": "passed", - "generated_at": "2026-06-29T14:00:38.8107466Z", + "generated_at": "2026-06-30T10:45:24.1772955Z", "configuration": "Development", - "skip_build": true, + "skip_build": false, "smoke_map_count": 2, "smoke_maps": [ {