From c8ec04e97d0d2691c68d53e025fcb7e22e343a41 Mon Sep 17 00:00:00 2001 From: Erik Date: Sat, 5 Sep 2026 18:49:22 +0200 Subject: [PATCH] docs #477: bound first-failure reporting and extended reproduction --- .../477-first-failure-contract.md | 87 ++++ .../route-477-extended-stability.txt | 438 ++++++++++++++++++ 2 files changed, 525 insertions(+) create mode 100644 docs/research/2026-09-01-overhaul/477-first-failure-contract.md create mode 100644 tools/overhaul-selfgate/route-477-extended-stability.txt diff --git a/docs/research/2026-09-01-overhaul/477-first-failure-contract.md b/docs/research/2026-09-01-overhaul/477-first-failure-contract.md new file mode 100644 index 00000000..65422cc5 --- /dev/null +++ b/docs/research/2026-09-01-overhaul/477-first-failure-contract.md @@ -0,0 +1,87 @@ +# #477 — preserve the first swapchain failure + +2026-09-05. Base `cd888a493`. Bounded diagnostic/error-propagation repair, +not a repair claim for the AMD reset. FPS remains deferred; G4 remains FAIL. + +## Evidence and boundary + +`477-cathedral-recurrence.md` records the owner's approximately 16-minute +cathedral session ending in device loss at an abandoned-frame timeline submit. +At this base, `VulkanSwapchain.TryAcquire` discards the original VkResult after +`OnAcquire` classifies it. `SwapchainBackbuffer.TryAcquire` maps Fail to false; +`VulkanGpuDevice.TryBeginFrame` consequently attempts an empty timeline submit. +`VulkanSwapchain.Present` likewise discards fatal results into a Fail action +that its adapter maps to false (recreation). This hides the first failing API. + +The already-existing `VulkanCallException` retains operation and exact Result. +The already-existing policy distinguishes normal unavailable/recreation cases +from Fail. Preserve that distinction at the actual native-call boundaries. + +Primary API references inspected by the lead on 2026-09-05: +[Khronos acquire](https://docs.vulkan.org/refpages/latest/refpages/source/vkAcquireNextImageKHR.html) +and [Khronos present](https://docs.vulkan.org/refpages/latest/refpages/source/vkQueuePresentKHR.html). +Acquire can return Success, Suboptimal, Timeout, NotReady, OutOfDate, and fatal +results including DeviceLost. Present likewise distinguishes usable/recreation +results from fatal ones. The existing policy is retained, not redesigned. +There is no retail Vulkan counterpart: this changes backend error reporting, +not any AC-specific decision, membership, drawing, or accepted-frame behavior. + +## Implementation contract + +Allowed production file: `src/AcDream.App/Rendering/Gpu/Vk/VulkanSwapchain.cs`. +Allowed tests: new `tests/AcDream.App.Tests/Rendering/Gpu/Vk/VulkanSwapchainFailureTests.cs` +and, only if needed, existing `VulkanSwapchainConfigurationTests.cs` beside it. +Lead owns this contract, verification, register decision, and ledgers. + +After each native acquire/present call, classify using the existing policy. +If the action is Fail, throw the existing VulkanCallException with the original +Result and operation `vkAcquireNextImageKHR` or `vkQueuePresentKHR`. Otherwise +return the unchanged action. Do not apply the success-only Check indiscriminately +to Suboptimal/Timeout/NotReady/OutOfDate. The uncreated-swapchain path remains +RecreateNow without invoking native acquire. Update the obsolete untested class +comment only to the actual coverage now provided. + +No changes to frame serial retirement, teardown, exception suppression, +recovery/retry policy, synchronization, shaders, pacing, native settings, +graphics quality, package, or scene behavior. No new logging toggle/framework, +new exception type, diagnostic owner, interface, or production test hook. + +## Verification required + +Use the existing test-side INativeContext/UnmanagedCallersOnly pattern to call +the real VulkanSwapchain methods with controlled native results. Tests must +prove the actual production boundaries (not just a copied classification): + +1. Acquire DeviceLost and another fatal result throw with exact operation and + Result; present does the same. Include an unknown negative error as a guard + against silently weakening the policy's default fatal path. +2. Acquire Success/Suboptimal/Timeout/NotReady/OutOfDate return the unchanged + actions; present Success/Suboptimal/OutOfDate likewise. Successful acquire + preserves its native image index. No invented assertion on failed-call index. +3. An uncreated swapchain returns RecreateNow without calling native acquire. +4. Restore old acquire/present result handling separately using apply_patch; + the respective fatal tests must fail. Restore the fix and rerun green. + Keep TRXs/logs under artifacts/477-first-failure; no retry laundering. +5. Release build 0 errors, focused tests including existing configuration, + frame-flight, acquisition, synchronization and capture-validity classes. + No build or test while either graphical client is running. + +The lead independently checks call flow through the unchanged adapters and +frame loop, runs the integrated Release lane, and checks the bounded diff. +One independent production/API review; retail port review is inapplicable to +this backend-only change. No intentional retail deviation is introduced; if +implementation exceeds that statement, stop for a contract/register decision. + +## Follow-on test and stop rules + +After review and green build, run a longer non-validation cathedral/Neftet +reproduction, retaining exact binary/configuration/process/evidence identities. +Automation is not the identical owner session; state that limitation. A clean +run does not prove the driver's initiating fault fixed. Record PNG PASS/FAIL +provisionally and close only our test client gracefully. No simultaneous client, +build/test, unbounded stress, force kill, or main merge. + +Implementer returns without committing or launching clients. Build red twice, +contract ambiguity, any need for an additional production file, or third fix +round stops the chunk and is reported. Independent tests and raw failures are +required before a diagnostic PASS; #477 stability remains separately open. diff --git a/tools/overhaul-selfgate/route-477-extended-stability.txt b/tools/overhaul-selfgate/route-477-extended-stability.txt new file mode 100644 index 00000000..612aa76f --- /dev/null +++ b/tools/overhaul-selfgate/route-477-extended-stability.txt @@ -0,0 +1,438 @@ +# #477 extended non-validation reproduction, not a performance or exact owner-session gate. +# Approximately 21 minutes of dwell plus movement/loading; explicit terminal graceful close. +# Owner crash trajectory is unknown. Scripted workload does not prove its exact reproduction. +# High/MSAA4, 1280x720, recipe10. Every held input is balanced. +wait world-ready 180000 +wait world-visible 300000 +resize 1280 720 +wait framebuffer 1280 720 30000 +renderpack select high +wait render-pack high 90000 +sleep 5000 +checkpoint 477_long_00_login +screenshot 477-long-00-login 15000 + +# Phase 1: cathedral_hall +command /teleloc F4180104 36.9 48.7 169.805 1 0 0 0 +wait materialized 1 180000 +wait world-visible 300000 +sleep 5000 +checkpoint 477_long_1_arrival +screenshot 477-long-1-arrival 15000 +# Minute 1 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input press CombatToggleCombat +sleep 1000 +sleep 30000 +sleep 30000 +checkpoint 477_long_1_minute_1 +# Minute 2 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_1_minute_2 +# Minute 3 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_1_minute_3 +# Minute 4 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_1_minute_4 +# Minute 5 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_1_minute_5 +# Minute 6 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input press CombatToggleCombat +sleep 1000 +sleep 30000 +sleep 30000 +checkpoint 477_long_1_minute_6 +screenshot 477-long-1-settled 15000 + +# Phase 2: cathedral_stairwell +command /teleloc F4180113 39.502899 19.832422 180.976700 1 0 0 0 +wait materialized 2 180000 +wait world-visible 300000 +sleep 5000 +checkpoint 477_long_2_arrival +screenshot 477-long-2-arrival 15000 +# Minute 1 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input press CombatToggleCombat +sleep 1000 +sleep 30000 +sleep 30000 +checkpoint 477_long_2_minute_1 +# Minute 2 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_2_minute_2 +# Minute 3 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_2_minute_3 +# Minute 4 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_2_minute_4 +# Minute 5 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_2_minute_5 +# Minute 6 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input press CombatToggleCombat +sleep 1000 +sleep 30000 +sleep 30000 +checkpoint 477_long_2_minute_6 +screenshot 477-long-2-settled 15000 + +# Phase 3: cathedral_return +command /teleloc F4180104 36.9 48.7 169.805 1 0 0 0 +wait materialized 3 180000 +wait world-visible 300000 +sleep 5000 +checkpoint 477_long_3_arrival +screenshot 477-long-3-arrival 15000 +# Minute 1 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input press CombatToggleCombat +sleep 1000 +sleep 30000 +sleep 30000 +checkpoint 477_long_3_minute_1 +# Minute 2 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_3_minute_2 +# Minute 3 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_3_minute_3 +# Minute 4 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_3_minute_4 +# Minute 5 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +sleep 30000 +sleep 30000 +checkpoint 477_long_3_minute_5 +# Minute 6 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input press CombatToggleCombat +sleep 1000 +sleep 30000 +sleep 30000 +checkpoint 477_long_3_minute_6 +screenshot 477-long-3-settled 15000 + +# Phase 4: neftet +command /teleloc 8763000E 40.4574 129.281 8.004999 1 0 0 0 +wait materialized 4 180000 +wait world-visible 300000 +sleep 5000 +checkpoint 477_long_4_arrival +screenshot 477-long-4-arrival 15000 +# Minute 1 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input down MovementJump +sleep 350 +input up MovementJump +sleep 2500 +input press CombatToggleCombat +sleep 1000 +sleep 30000 +sleep 30000 +checkpoint 477_long_4_minute_1 +# Minute 2 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input down MovementJump +sleep 350 +input up MovementJump +sleep 2500 +sleep 30000 +sleep 30000 +checkpoint 477_long_4_minute_2 +# Minute 3 +input down MovementTurnRight +sleep 500 +input up MovementTurnRight +input down MovementForward +sleep 200 +input up MovementForward +sleep 1000 +input down MovementBackup +sleep 200 +input up MovementBackup +input down CameraRotateRight +sleep 300 +input up CameraRotateRight +input down MovementJump +sleep 350 +input up MovementJump +sleep 2500 +input press CombatToggleCombat +sleep 1000 +sleep 30000 +sleep 30000 +checkpoint 477_long_4_minute_3 +screenshot 477-long-4-settled 15000 + +checkpoint 477_long_complete +close-client +