docs: contract completed-frame capture repair and safe self-gate launch
This commit is contained in:
parent
350340d2ed
commit
6347e0f826
4 changed files with 137 additions and 4 deletions
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# under logs/selfgate-<stamp>-<label>/ with the PNGs, the client log, and a
|
||||
# run.json naming the exact commit.
|
||||
#
|
||||
# Rules: refuses to run while any AcDream.App process exists (never touch an
|
||||
# Rules: refuses to run while any AcDream.App or retail acclient exists (never touch an
|
||||
# owner-started client); closes only the client it started, gracefully.
|
||||
#
|
||||
# Usage (from the worktree root):
|
||||
|
|
@ -26,8 +26,8 @@ $ErrorActionPreference = 'Stop'
|
|||
$repo = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
|
||||
$exe = Join-Path $repo 'src\AcDream.App\bin\Release\net10.0\AcDream.App.exe'
|
||||
if (-not (Test-Path -LiteralPath $exe)) { throw "Release client not built: $exe" }
|
||||
if (Get-Process -Name AcDream.App -ErrorAction SilentlyContinue) {
|
||||
throw 'An AcDream.App process is already running (owner client?). Not launching.'
|
||||
if (Get-Process -Name AcDream.App, acclient -ErrorAction SilentlyContinue) {
|
||||
throw 'An AcDream.App or retail acclient process is already running. Not launching.'
|
||||
}
|
||||
|
||||
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
|
||||
|
|
@ -57,7 +57,7 @@ $clientLog = Join-Path $out 'client.log'
|
|||
Write-Host "self-gate '$Label' at $commit (dirty=$dirty) -> $out"
|
||||
$proc = Start-Process -FilePath $exe -ArgumentList @('--session-config', (Resolve-Path $Session).Path) `
|
||||
-RedirectStandardOutput $clientLog -RedirectStandardError (Join-Path $out 'client.err.log') `
|
||||
-PassThru -WindowStyle Normal
|
||||
-PassThru -WindowStyle Hidden
|
||||
|
||||
if (-not $proc.WaitForExit($TimeoutSeconds * 1000)) {
|
||||
Write-Warning "client still running after $TimeoutSeconds s; requesting graceful close"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue