diff --git a/docs/research/2026-09-01-overhaul/476-completed-frame-capture-contract.md b/docs/research/2026-09-01-overhaul/476-completed-frame-capture-contract.md new file mode 100644 index 00000000..90b333fa --- /dev/null +++ b/docs/research/2026-09-01-overhaul/476-completed-frame-capture-contract.md @@ -0,0 +1,92 @@ +# #476 — capture the submitted current frame, never uninitialized readback + +Lead contract2026-09-05. NOT IMPLEMENTED. Read the full +476-capture-lifetime-diagnosis.md first: it records the lead's production +trace, failed PNG and named-retail/paired-binary screenshot boundary. This +is a modern Vulkan retained-copy lifetime repair, not a new AC algorithm. + +## Bounded change + +Move the existing IPrivateFrameScreenshot invocation from +PrivatePresentationRenderer's still-open render phase to the outer +RenderFrameOrchestrator's successfully closed frame boundary. The sequence +is resource/world/private drawing, GPU measurement close, ONE GPU frame close, +capture, CPU diagnostics, shadow comparison, lifecycle checkpoint. Keep the +existing immutable outcome fields truthful: ScreenshotCaptured reflects that +post-close capture, while portal/private presentation facts remain those of +the frame just drawn. Wire the same optional capture adapter through +FrameRootComposition; no second frame owner or screenshot queue. + +Preserve the existing begin/render/measurement/recovery/close error contract: +Begin failure does not close; every successful Begin attempts exactly one +End, including render/measurement failure; recovery remains before End when +render fails; aggregated errors retain their original ordering. A close +failure must not execute capture/post-close consumers or cause a second End. +Capture/diagnostic/post-diagnostic failure AFTER close must propagate without +trying to close/recover a finished GPU frame. Zero-area input opens nothing, +captures nothing and leaves queued requests for a later renderable frame. +Do not alter the idempotent GpuDeviceFrameLifetime clearing rule. + +In VulkanGpuDevice's existing capture fields/methods and EndFrame, ensure +readback is valid only after an actual successful submission containing the +retained image-to-buffer copy. Allocation/resize or command recording alone +is not validity. Prevent an open/unsubmitted frame, missing copy, skipped +acquisition, failed submission or new-size buffer from being advertised as +the newly completed requested frame. Use minimal local state on the existing +owner; reset it at the actual relevant lifetime edges. Preserve the correct +bring-up caller that already reads after frame close. Do not read the +swapchain after present or change semaphore/flight/resource retirement. + +Retain opt-in capture and zero copies/allocations when off. Keep the existing +DeviceWaitIdle readback behavior for a valid submitted capture; do not add +waits elsewhere. No sleeps, first-image discard, guessed warmup, retry-until- +pretty loop, shader/quality change or screenshot naming/orientation rewrite. +The controller's one-request-per-frame, complete/failed status and atomic PNG +behavior remain intact. Do not bundle unrelated stale GL comments/cleanup. + +## Files and ownership + +Scope: RenderFrameOrchestrator, PrivatePresentationRenderer, +FrameRootComposition; capture-only portions of VulkanGpuDevice and its +Resources partial; existing focused orchestrator/private/composition, +screenshot/lifecycle and Vulkan capture tests; relevant architecture paragraph. +No Runtime/world/lighting/mesh/walk edits. Any intentional behavioral deviation +needs its register row in the landing commit; none is expected. + +Use a fresh codex/s5-476-openai-impl scratch at the commit containing this +contract. #477 is in a DIFFERENT scratch and touches other portions of the +same Vulkan partials. Do not copy/edit its source. Root integrates narrow +accepted changes and preserves both; do not perform a whole-file overwrite. +No agent commit/graphical launch or extra agents. Both AcDream.App and retail +acclient must be absent before EVERY build/test. + +## Proof + +Exercise the REAL orchestrator plus real PrivatePresentationRenderer and +FrameScreenshotController composition with a fake GPU/frame whose distinct +frame pixels become readable ONLY at End/submission. Do not merely assert a +manually written phase list. Startup and actual-size-change first captures +must carry the newly submitted pixels, with exact orientation/size. Reuse +existing fake-GPU/test fixtures rather than a new recording framework. + +Verify real phase order and every failure boundary above, queued requests, +zero-area then resumed frame, and capture-off behavior. For native validity, +exercise the actual production state transitions/call binding, not an unused +Boolean policy helper. Capture before first submit, after resize before its +first copy, while open and after failed/no-copy submission must not read old +bytes as a valid current frame. Existing bring-up/format tests remain green. + +Two actual-production mutations: restore capture before End; then mark the +new buffer/recorded-but-unsubmitted copy as valid. Each must fail its intended +pixel/validity assertion, not compilation or test setup. Restore exact raw +hashes, rebuild Release0W0E and run affected hermetic lanes with zero new skips. +Return commands/TRX/hashes and precise claim boundaries. Root independently +verifies, then sequential behavior/retail and production/lifetime review +lenses follow within the owner's ten-review limit. + +Graphical closure only after #477's synchronization run is clean and no agent +is building/testing: fresh Release, ACE9000 up, both clients absent, one +bounded real Vulkan run. Capture first requested frame at startup and across +two REAL different framebuffer sizes, plus a settled portal/world frame. +Preserve every PNG and record PASS/FAIL paths, provisional until owner looks. +This repair alone cannot close #477 or the failed G4 owner matrix. diff --git a/docs/research/2026-09-01-overhaul/478-480-readonly-diagnosis.md b/docs/research/2026-09-01-overhaul/478-480-readonly-diagnosis.md index 0749e6d2..dd0ad661 100644 --- a/docs/research/2026-09-01-overhaul/478-480-readonly-diagnosis.md +++ b/docs/research/2026-09-01-overhaul/478-480-readonly-diagnosis.md @@ -99,3 +99,36 @@ do not create a global telemetry framework or resurrect camera-flood light selection. No current PNG/light-membership witness exists for the failed owner session. If a genuinely required retail fact cannot be recovered statically, follow the owner's stop rule; do not invent it. + +### Lead static follow-up (no lighting repair or live witness) + +The lead independently read CellManager::ChangePosition, minimize_envcell_lighting, +DrawEnvCell and SetStaticLightingVertexColors, then checked the paired exe +above using its PE sections. Exact body ranges/hashes: + +| VA / bytes | SHA-256 | +| --- | --- | +|004559B0 / 555|DDF73D34A7A8099672191EB5A18A9C21F73D4A3A0B379B94840D709AD6E64D49| +|0054C170 / 58|C948472BF8FE01BD318F4EB2BE0A6FD0FB1D87BE19114F776C613CCE3737250D| +|0059F170 / 293|408D9818DD02750825F36D05824D3562F9BB62D3FEFABF1DD172375A3C6C91B2| +|0059CFE0 / 759|E0148A7FA69A56ED2D4E49201A8284AA5907AE314FF9A8CCC9E77B3FC3DDD340| + +The ambient branch loads0079B7FC (raw0039B7FC), bytesCDCC4C3E =0.2f, +and passes whiteFFFFFFFF. Static/dynamic capacity data0081EC94/98 is +40/7 respectively (bytes2800000007000000). DrawEnvCell's0059F1F6 +E8E5DDFFFF calls0059CFE0. That routine's static loop increments/compares +against num_static_lights at0059D17E before looping; it does not share an +eight-entry EnvCell selector with the dynamic hardware lights. This confirms +the relevant difference, not its activation in the failed Town Network frame. + +Lead also read the current filmic shader and its gamma helpers/default +settings, then independently evaluated its scalar formula with no bloom, +rays or volumetric contribution, saturation/contrast1. At screen center, +display inputs0.20/0.10/0.05 map to approximately0.140/0.052/0.023 under +exposure0.8/fullACES; corner strength0.245 further dims them. These are +formula examples, NOT measured current scene pixels. No parameter is changed. + +Before the next unattended run, the existing self-gate runner was narrowly +hardened to refuse either client and explicitly use WindowStyle Hidden. +It already uses a real hidden Vulkan window through exact-framebuffer mode. +No route/rendering behavior, graphics profile or quality was changed. diff --git a/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md b/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md index 650015d4..b559261d 100644 --- a/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md +++ b/docs/research/2026-09-01-overhaul/s5-consumers-material-closeout-packet.md @@ -4706,3 +4706,11 @@ old route labels "Sawato"/"Rynthid" are unreliable identifiers. Evidence and candidate elevated2D31 complex are in479-rynthid-location-evidence.md. A read-only object/part trace is in progress; transform cause still unproven. All #478/#481, #476, exact route, C1c/C2/full-G4 obligations in§49 remain open. + +Confirmed #476 capture-before-submit now has its separate bounded contract, +476-completed-frame-capture-contract.md. A fresh scratch may implement it +independently; root must integrate only accepted capture portions alongside +#477, never overwrite its unrelated Vulkan barrier changes. Graphical closure +waits for477 validation and an exclusive no-build/test window. The self-gate +runner now explicitly starts hidden and refuses either graphical client; +PowerShell parse/diff check pass. No rendering policy/quality change. diff --git a/tools/overhaul-selfgate/run-selfgate.ps1 b/tools/overhaul-selfgate/run-selfgate.ps1 index eefe970f..1f3da619 100644 --- a/tools/overhaul-selfgate/run-selfgate.ps1 +++ b/tools/overhaul-selfgate/run-selfgate.ps1 @@ -6,7 +6,7 @@ # under logs/selfgate--