Attach captured canvas payloads to document snapshots

This commit is contained in:
2026-06-05 18:03:33 +02:00
parent d0412e3bf9
commit f4f6eb903e
10 changed files with 298 additions and 23 deletions

View File

@@ -261,11 +261,12 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p
automation, including the OpenGL command-plan support counts for that upload
stream, and is covered by
`pano_cli_simulate_document_render_smoke`.
- `pano_cli plan-canvas-document-snapshot` exposes the metadata-only bridge from
live canvas state toward `pp_document::CanvasDocument`, including dimensions,
active layer/frame, layer visibility/opacity/alpha/blend metadata, frame
durations, and pending renderer payload-readback counts, and is covered by
`pano_cli_plan_canvas_document_snapshot_smoke`.
- `pano_cli plan-canvas-document-snapshot` exposes the bridge from live canvas
state toward `pp_document::CanvasDocument`, including dimensions, active
layer/frame, layer visibility/opacity/alpha/blend metadata, frame durations,
captured RGBA8 face payloads, and remaining renderer payload-readback counts,
and is covered by `pano_cli_plan_canvas_document_snapshot_smoke` plus the
payload-bearing snapshot smoke.
- `pano_cli save-document-project` writes that pure document export to a PPI
file and is covered by `pano_cli_save_document_project_roundtrip_smoke`,
which inspects and loads the generated file.

View File

@@ -11,7 +11,7 @@ and validation command.
| Capability | Current Area | Target Owner | Required Tests |
| --- | --- | --- | --- |
| PPI open/save | `Canvas`, serializer, dialogs | `pp_document`, `pp_assets`, `pano_cli` | Round-trip tiny project, old-version fixture, corrupt/truncated fixture, metadata-only live-canvas-to-`pp_document` snapshot projection with pending renderer payload-readback counts |
| PPI open/save | `Canvas`, serializer, dialogs | `pp_document`, `pp_assets`, `pano_cli` | Round-trip tiny project, old-version fixture, corrupt/truncated fixture, live-canvas-to-`pp_document` snapshot projection with captured RGBA8 payloads and pending renderer-readback counts |
| Open-document routing | `App::open_document` | `pp_app_core`, `pano_cli`, `pp_panopainter_ui`, `pp_document`, `pp_assets` | Project/ABR/PPBR route tests, malformed path tests, open-action plan tests, CLI route/action smoke, app open smoke |
| Document session decisions | `App::open_document`, `App::request_close`, save hotkeys, file menu, dialogs | `pp_app_core`, `pano_cli`, `pp_panopainter_ui` | Clean/dirty/prompt-open/save/save-as/save-version/save-before-workflow/name/new-document resolution/overwrite/version-target decision tests, CLI session, new-document, document-file, and document-version smoke, app close/open/save/new/browse smoke |
| Version metadata | `scripts/pre-build.py`, `version.*` | build system, `pp_foundation` | Generated header smoke test, missing-tag behavior |

View File

@@ -465,6 +465,14 @@ agent or engineer to remove them without reconstructing context from chat.
snapshot from retained `Canvas` dimensions, active layer/frame, layer
visibility/opacity/alpha/blend metadata, and frame durations. Renderer-owned
cube-face pixel payload readback remains open under DEBT-0010/DEBT-0036.
- 2026-06-05: DEBT-0010 was narrowed again. The canvas snapshot planner now
accepts captured RGBA8 face payloads and attaches them to
`pp_document::CanvasDocument`; `pano_cli plan-canvas-document-snapshot
--captured-face-payloads-per-layer` covers payload-bearing automation, and
`src/legacy_document_canvas_services.*` exposes an opt-in dirty-face payload
snapshot path backed by retained `Layer::snapshot()` readback. Live save,
export, and action-command adoption of that payload-bearing snapshot remains
open under DEBT-0010/DEBT-0013/DEBT-0036.
## Open Debt
@@ -478,7 +486,7 @@ agent or engineer to remove them without reconstructing context from chat.
| DEBT-0007 | Open | Modernization | `vcpkg.json` and `windows-msvc-vcpkg-headless` are validated for the headless Windows component matrix, and root CMake now exposes a focused `panopainter_platform_build_vcpkg_ui_core` target for the vcpkg-backed `pp_ui_core`/tinyxml2 boundary, but app targets still use vendored libraries and Android/Apple triplets are not proven | Dependency migration must stay incremental while SDK/patched/vendor dependencies remain in use | `cmake --preset windows-msvc-vcpkg-headless`; `ctest --preset desktop-fast-vcpkg --build-config Debug`; `cmake --build --preset windows-msvc-default --config Debug --target panopainter_platform_build_vcpkg_ui_core` | Component targets consume vcpkg packages where reliable and desktop app, Android, and Apple triplets are validated or explicitly documented as permanent vendor exceptions |
| DEBT-0008 | Open | Modernization | `windows-msvc-default` and `windows-msvc-vcpkg-headless` explicitly select Visual Studio 18 2026 for local validation, but non-VS2026 CMake executables on PATH may not know that generator | The local machine has VS 2026, but using an older CMake can still default to Ninja or reject the VS 2026 generator | `cmake --preset windows-msvc-default`; `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter`; `ctest --preset desktop-fast --build-config Debug` | The repo automation invokes or locates a CMake executable that supports `Visual Studio 18 2026`, and VS 2026 generator validation is the normal Windows path without manual tool selection |
| DEBT-0009 | Open | Modernization | Android root CMake validation currently builds headless targets only, while retained standard/Quest/Focus package CMake paths now have a refreshed CMake 3.10/C++23 baseline outside root CMake; automation queries `sdkmanager`, installs newer or missing SDK Manager NDK/CMake packages, selects the resulting pair before configure, and reports update decisions; root CMake exposes non-default platform-build and retained native package validation targets | Platform app entrypoints still live in legacy Gradle/CMake projects and need Phase 6 alignment | `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64`; `cmake --build --preset android-x64`; `cmake --build --preset android-quest-arm64`; `cmake --build --preset android-focus-arm64`; `cmake --build --preset windows-msvc-default --config Debug --target panopainter_platform_build_android_assets`; `powershell -ExecutionPolicy Bypass -File scripts\automation\android-legacy-package-build.ps1 -Packages standard`; `powershell -ExecutionPolicy Bypass -File scripts\automation\android-legacy-package-build.ps1 -Packages quest,focus -ConfigureOnly`; `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -ReadinessOnly -AndroidNativeChecks -PackageKinds android-standard-apk,android-quest-apk,android-focus-apk`; `cmake --build --preset windows-msvc-default --config Debug --target panopainter_android_native_package_smoke` | Android standard, Quest, and Focus/Wave package targets consume shared component targets and have package smoke commands |
| DEBT-0010 | Open | Modernization | `pp_document` is a pure layer/frame/document/undo-history model with alpha-lock metadata, snapshot construction, per-layer frame metadata, renderer-free RGBA8 face payload storage, snapshot-embedded face-payload validation, renderer-free alpha8 selection-mask storage, PPI import/export helpers, stroke-script-to-face-payload CLI automation, `pp_paint_renderer` document face/frame compositors, renderer-neutral six-face texture upload, OpenGL command-planner validation through CLI render automation, and metadata-only live Canvas snapshot projection through `pp_app_core`/`legacy_document_canvas_services`, but legacy save/action commands and renderer-owned cube-face pixel payload readback are not yet wired | Keep extraction incremental while preserving app behavior | `ctest --preset desktop-fast --build-config Debug`; `pano_cli create-document --width 64 --height 32 --layers 2`; `pano_cli load-project --path tests\data\projects\minimal-project.ppi`; `pano_cli simulate-document-render --width 64 --height 32`; `pano_cli plan-canvas-document-snapshot --width 64 --height 32`; `pp_document_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pp_paint_renderer_compositor_tests`; `pp_app_core_document_canvas_tests`; `pano_cli_simulate_document_edits_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_simulate_document_render_smoke`; `pano_cli_plan_canvas_document_snapshot_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Legacy document behavior is represented by `pp_document`/`pp_paint_renderer` tests and the app consumes it through a boundary/facade |
| DEBT-0010 | Open | Modernization | `pp_document` is a pure layer/frame/document/undo-history model with alpha-lock metadata, snapshot construction, per-layer frame metadata, renderer-free RGBA8 face payload storage, snapshot-embedded face-payload validation, renderer-free alpha8 selection-mask storage, PPI import/export helpers, stroke-script-to-face-payload CLI automation, `pp_paint_renderer` document face/frame compositors, renderer-neutral six-face texture upload, OpenGL command-planner validation through CLI render automation, live Canvas snapshot projection through `pp_app_core`/`legacy_document_canvas_services`, and captured RGBA8 payload attachment to `pp_document`, but legacy save/action commands, full live payload-snapshot adoption, and renderer-owned cube-face readback ownership are not yet wired | Keep extraction incremental while preserving app behavior | `ctest --preset desktop-fast --build-config Debug`; `pano_cli create-document --width 64 --height 32 --layers 2`; `pano_cli load-project --path tests\data\projects\minimal-project.ppi`; `pano_cli simulate-document-render --width 64 --height 32`; `pano_cli plan-canvas-document-snapshot --width 64 --height 32`; `pano_cli plan-canvas-document-snapshot --captured-face-payloads-per-layer 1`; `pp_document_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pp_paint_renderer_compositor_tests`; `pp_app_core_document_canvas_tests`; `pano_cli_simulate_document_edits_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_simulate_document_render_smoke`; `pano_cli_plan_canvas_document_snapshot_smoke`; `pano_cli_plan_canvas_document_snapshot_payload_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Legacy document behavior is represented by `pp_document`/`pp_paint_renderer` tests and the app consumes it through a boundary/facade |
| DEBT-0011 | Open | Modernization | `package-smoke` validates the Windows CMake app artifact and launch-folder DLL payload, and reports a structured package readiness matrix for Windows AppX, Android standard/Quest/Focus APKs, Apple bundles, Linux app output, and WebGL output; the Windows app smoke passes the configure-time CMake executable so VS 2026 generator validation does not depend on `cmake` from PATH, retained Android package native CMake paths, and retained Linux/WebGL CMake baseline metadata are reachable from package validation and root CMake package-readiness targets, but Windows AppX/APK/Linux/Apple/WebGL package outputs are still `blocked` because root CMake package targets do not exist yet | Platform package targets are not migrated to root CMake yet | `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug`; `cmake --build --preset windows-msvc-default --config Debug --target panopainter_windows_app_package_smoke`; `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -ReadinessOnly -AndroidNativeChecks -PackageKinds android-standard-apk,android-quest-apk,android-focus-apk`; `cmake --build --preset windows-msvc-default --config Debug --target panopainter_android_native_package_smoke`; `cmake --build --preset windows-msvc-default --config Debug --target panopainter_linux_webgl_package_readiness`; `python scripts/dev/check_package_smoke_readiness.py`; `bash -n scripts/automation/package-smoke.sh` | Package-smoke builds and validates Windows AppX, Android APK variants, Linux app, Apple bundles, and WebGL output where local toolchains are present |
| DEBT-0012 | Open | Modernization | `pp_ui_core` uses vcpkg tinyxml2 on `windows-msvc-vcpkg-headless`, but retains `pp_vendor_tinyxml2` for default and unproven platform presets | Mobile/AppX/Apple triplets and app packaging still need validation before removing the vendored fallback | `ctest --preset desktop-fast-vcpkg --build-config Debug`; `ctest --preset desktop-fast --build-config Debug`; `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64` | All supported presets consume vcpkg tinyxml2 or document a permanent vendored exception |
| DEBT-0013 | Open | Modernization | `pp_assets`, `pp_document`, `pano_cli inspect-project`, `pano_cli load-project`, and `pano_cli save-project` validate the fixed PPI header, thumbnail/body byte layout, generated multi-layer/multi-frame PPI writing with explicit layer opacity/blend/alpha-lock/visibility metadata, per-layer frame durations, metadata-only and targeted dirty-face-payload save/load round-trips, layer/frame index, dirty-face descriptors, dirty-face PNG payload metadata, asset-level RGBA PNG payload decoding, pure document-to-PPI export, CLI document export automation, file-writing document export automation, stroke-script-generated document payload export, and decoded pixel attachment to `pp_document`, but full legacy PPI round-trip parity is not yet extracted | Full PPI save parity requires staged extraction of legacy `Canvas` serialization and image/layer payload handling | `ctest --preset desktop-fast --build-config Debug`; `pp_assets_image_pixels_tests`; `pp_assets_ppi_header_tests`; `pp_document_ppi_import_tests`; `pp_document_ppi_export_tests`; `pano_cli_inspect_project_layout_smoke`; `pano_cli_load_project_metadata_smoke`; `pano_cli_save_project_roundtrip_smoke`; `pano_cli_save_project_payload_roundtrip_smoke`; `pano_cli_simulate_document_export_smoke`; `pano_cli_save_document_project_roundtrip_smoke`; `pano_cli_apply_stroke_script_roundtrip_smoke`; `pano_cli_apply_stroke_script_rejects_tiny_canvas` | Full PPI load/save fixtures cover thumbnails, decoded layer face payloads attached to documents, frames, corrupt payloads, dirty-face payload saving, arbitrary legacy canvas payload/layout combinations, and legacy app round-trip compatibility |

View File

@@ -665,10 +665,11 @@ bridge before the legacy `Canvas::clear` adapter continues.
`pano_cli plan-canvas-document-snapshot` exposes the app-core projection from
live canvas metadata into a pure `pp_document::CanvasDocument`, including
dimensions, active layer/frame, layer visibility/opacity/alpha/blend metadata,
frame durations, and pending renderer payload-readback counts; the retained
`legacy_document_canvas_services` bridge now builds the same metadata-only
snapshot from live `Canvas` state while cube-face pixel payload extraction
remains under `DEBT-0010`/`DEBT-0036`.
frame durations, captured RGBA8 face payloads, and remaining renderer
payload-readback counts; the retained `legacy_document_canvas_services` bridge
now builds the same metadata snapshot from live `Canvas` state and has an
opt-in dirty-face payload snapshot path backed by retained `Layer::snapshot()`
readback while live save/export adoption remains under `DEBT-0010`/`DEBT-0036`.
`pano_cli plan-image-import` exposes app-core planning for File > Import image
route decisions, including wide equirectangular images, legacy vertical cube
strips, regular transform-placement images, and invalid image dimensions; live
@@ -2189,18 +2190,19 @@ Results:
- `pp_app_core_document_canvas_tests` passed, covering clear-current-layer
undo/dirty intent, no-canvas no-op behavior, and invalid clear color
rejection, service dispatch color forwarding, no-op execution preservation,
invalid execution color rejection, and metadata-only canvas-to-`pp_document`
invalid execution color rejection, and canvas-to-`pp_document`
snapshot projection with layer visibility, opacity, alpha-lock, blend mode,
frame duration, active layer/frame, default-name, no-canvas, bad blend, and
bad duration coverage.
frame duration, active layer/frame, captured RGBA8 face payload attachment,
default-name, no-canvas, bad blend, bad payload, and bad duration coverage.
- `pano_cli_plan_canvas_clear_smoke`,
`pano_cli_plan_canvas_clear_no_canvas_smoke`, and
`pano_cli_plan_canvas_clear_rejects_bad_color` passed and expose toolbar
canvas clear planning as JSON automation.
- `pano_cli_plan_canvas_document_snapshot_smoke` and
`pano_cli_plan_canvas_document_snapshot_no_canvas` passed and expose the
metadata-only live-canvas-to-`pp_document` projection, including pending
renderer payload-readback counts, as JSON automation.
`pano_cli_plan_canvas_document_snapshot_payload_smoke` plus the no-canvas
rejection smoke passed and expose live-canvas-to-`pp_document` projection,
including captured-versus-pending renderer payload-readback counts, as JSON
automation.
- `pp_app_core_document_import_tests` passed, covering wide equirectangular,
legacy vertical cube strip, regular transform-placement, and invalid-dimension
import route decisions, equirectangular service dispatch, transform import