Add roadmap finalization task audit

This commit is contained in:
2026-06-14 10:43:37 +02:00
parent 6b628abfc0
commit c9fb9fa986
2 changed files with 365 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
# PanoPainter Modernization Roadmap
Status: live
Last updated: 2026-06-13
Last updated: 2026-06-14
This is the living roadmap for modernizing PanoPainter into independently
testable C++23 components while retaining all existing functionality. Keep this
@@ -62,6 +62,13 @@ queue, blocked queue, validation commands, and completion rules. Do not move the
percentage for a narrowed adapter or added planner unless a task in that file is
marked `Done` with validation and a debt/roadmap update.
The 2026-06-14 planning audit added measurable blockers for roadmap
finalization: component boundary self-tests (`ARCH-001`), renderer backend
contract freeze and conformance (`RND-007`, `RND-008`), opt-in Vulkan/Metal lab
targets (`RND-009`, `RND-010`), UI thread-affinity and checked-handle migration
(`UI-001`, `UI-002`), render/UI queue race coverage (`APP-001`), package gates
for backend/UI work (`PLT-010`), and historical task cleanup (`AUD-001`).
Recent 2026-06-13 retained preview reductions continue to narrow DEBT-0036:
`NodeStrokePreview::draw_stroke_immediate()` now also routes
feedback/material/composite planning and stroke-shader uniform assembly through
@@ -1829,6 +1836,11 @@ Gate:
Goal: prepare Vulkan and Metal without destabilizing the OpenGL parity path.
Status: not started. Do not start production Vulkan or Metal work until
`RND-007` and `RND-008` freeze and validate the renderer API backend contract.
`RND-009` and `RND-010` are opt-in lab targets only and must stay outside the
production app path.
Implementation tasks:
- Create non-default targets only after OpenGL backend parity:

View File

@@ -52,6 +52,30 @@ task id, points moved, validation command, and commit hash.
| `Blocked` | Needs a user decision, missing toolchain, or a prior task. |
| `Done` | Validated, documented, committed, and pushed. |
## Planning Audit - 2026-06-14
Current progress covers many retained stroke, draw-merge, export, platform,
and app-core planner seams, but it is not sufficient to declare the
modernization roadmap final. Missing coverage before Vulkan, Metal, and broad
UI rewrites:
- Renderer contract freeze: `pp_renderer_api` needs an explicit backend
conformance contract before any Vulkan or Metal lab can be useful.
- Backend conformance automation: OpenGL and recording backends need the same
command/resource/readback/transition fixtures that future Vulkan/Metal
targets must pass.
- Backend lab scaffolds: Vulkan and Metal must be opt-in, non-production
targets with validation-layer or command-encoding smoke tests only.
- UI safety: retained `Node` migration needs thread-affinity, checked handles,
scoped callbacks, and mutation-safe dispatch gates, not only one popup family.
- Threading safety: render/UI queue behavior needs race/regression tests around
cancellation, shutdown, nested dispatch, and cross-thread misuse.
- Platform gates: Apple/Linux/WebGL/AppX package readiness must be part of the
backend/UI gate because renderer and UI boundaries are platform-sensitive.
- Task hygiene: duplicate historical IDs and stale pending closeouts remain in
this tracker; new agents must treat `AUD-001` as documentation cleanup before
using historical score rows for accounting.
## Ready Queue
### MT-001 - Adopt Measurable Task Tracking
@@ -2441,6 +2465,334 @@ Validation:
ctest --preset desktop-fast --build-config Debug -R "pp_paint_renderer_stroke_execution|pp_paint_renderer_compositor" --output-on-failure
```
### AUD-001 - Normalize Historical Task Tracker Duplicates
Status: Ready
Score: no score movement
Debt: none
Scope: `docs/modernization/tasks.md`
Goal:
Clean the historical tracker rows that make current progress hard to audit
without changing code: duplicate `STR-010`, duplicate/ambiguous `STR-016`,
duplicate `STR-030`, malformed `RND-006` completed-task table shape, and stale
`pending` closeout rows.
Done Checks:
- Each historical task id has one active section or one clearly marked
historical alias note.
- No completed-task row has `pending` as a commit.
- Completed-task tables use a consistent Date/Task/Score/Validation/Commit
shape.
- The scorecard total is not changed unless backed by already committed rows.
Validation:
```powershell
rg -n "pending|### STR-010|### STR-016|### STR-030|RND-006" docs\modernization\tasks.md
git diff -- docs\modernization\tasks.md
```
### ARCH-001 - Add Component Boundary Dependency Self-Test
Status: Ready
Score: +2 pure component behavior ownership
Debt: `DEBT-0003`, `DEBT-0008`
Scope: `scripts/dev/`, `tests/CMakeLists.txt`, root `CMakeLists.txt`,
`docs/modernization/build-inventory.md`
Goal:
Add an automated boundary check that fails when pure component headers or
targets include platform SDK headers, OpenGL headers, retained `App::I`/
`Canvas::I` singletons, or backend-specific types outside allowed
`pp_renderer_gl` and `pp_platform_*` targets.
Done Checks:
- The check encodes allowed dependency direction for `pp_foundation`,
`pp_assets`, `pp_paint`, `pp_document`, `pp_renderer_api`,
`pp_paint_renderer`, `pp_ui_core`, `pp_app_core`, and platform/backend
targets.
- The check reports exact offending file, include, or target edge.
- Existing known legacy exceptions are explicit allowlist entries with debt ids.
- CTest registers the check under `desktop-fast`.
Validation:
```powershell
ctest --preset desktop-fast --build-config Debug -R "panopainter_component_boundary" --output-on-failure
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
```
### RND-007 - Freeze Renderer API Backend Contract
Status: Ready
Score: +2 renderer boundary and OpenGL parity
Debt: `DEBT-0036`, `DEBT-0064`
Scope: `src/renderer_api/*`, `src/renderer_gl/*`,
`src/paint_renderer/*`, `tests/renderer_api/*`,
`tests/renderer_gl/*`, `tests/paint_renderer/*`
Goal:
Define the minimum renderer contract that OpenGL, Vulkan, and Metal must share:
resource descriptors, lifetime rules, texture upload/readback, render-target
attachment, copy/blit semantics, viewport/scissor state, shader/program
binding, feature flags, frame capture, debug labels, and error/status returns.
Done Checks:
- `pp_renderer_api` documents and tests the backend-neutral contract without GL,
Vulkan, Metal, platform SDK, or window headers.
- `pp_renderer_gl` passes the same contract expectations through focused
backend tests or command-plan tests.
- `pp_paint_renderer` chooses only renderer-api feature/path data; it does not
branch on OpenGL-specific symbols.
- `DEBT-0064` has a removal path tied to a callback-only or renderer-owned
texture seam.
Validation:
```powershell
ctest --preset desktop-fast --build-config Debug -R "pp_renderer_api|pp_renderer_gl|pp_paint_renderer" --output-on-failure
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
```
### RND-008 - Add Backend Conformance Test Matrix
Status: Ready
Score: +2 hardening and future backend readiness
Debt: `DEBT-0036`
Depends: `RND-007`
Scope: `tests/renderer_api/`, `tests/renderer_gl/`, `tests/CMakeLists.txt`,
`CMakePresets.json`, `docs/modernization/build-inventory.md`
Goal:
Create reusable backend conformance fixtures that every renderer backend must
pass before it can be considered for production: command recording order,
resource creation failures, texture state transitions, copy/blit bounds,
readback byte size, framebuffer feedback path selection, and deterministic
golden/readback samples.
Done Checks:
- Recording backend and OpenGL backend run equivalent conformance cases where
possible.
- Backend-specific skips are explicit and tied to feature flags, not target
names.
- `desktop-fast` covers headless contract cases; `desktop-gpu` covers real GL
readback/golden cases.
- Future Vulkan/Metal lab targets can register the same fixture family without
changing paint-renderer tests.
Validation:
```powershell
ctest --preset desktop-fast --build-config Debug -R "pp_renderer_api|pp_renderer_gl|pp_paint_renderer" --output-on-failure
ctest --preset desktop-gpu --build-config Debug --output-on-failure
```
### RND-009 - Scaffold Opt-In Vulkan Lab Backend
Status: Blocked
Score: +2 hardening and future backend readiness
Debt: none
Depends: `RND-007`, `RND-008`
Blocked By: Vulkan SDK/package decision, validation-layer availability, and
OpenGL conformance baseline stability.
Scope: `src/renderer_vulkan_lab/*`, root `CMakeLists.txt`,
`tests/renderer_vulkan_lab/*`, `docs/modernization/build-inventory.md`
Goal:
Add a non-default `pp_renderer_vulkan_lab` target that proves the renderer-api
contract can map to Vulkan command buffers, resource lifetimes, layout
transitions, and ping-pong compositing without entering the production app path.
Done Checks:
- Target is opt-in and never linked by `PanoPainter`.
- Smoke tests create/destroy a device, allocate a tiny render target, execute a
clear/copy/readback path where local Vulkan support exists, and skip cleanly
when unavailable.
- Validation-layer failures fail the lab test.
- No production OpenGL behavior changes.
Validation:
```powershell
cmake --build --preset windows-msvc-default --config Debug --target pp_renderer_vulkan_lab_tests
ctest --preset desktop-gpu --build-config Debug -R "pp_renderer_vulkan_lab" --output-on-failure
```
### RND-010 - Scaffold Opt-In Metal Lab Backend
Status: Blocked
Score: +2 hardening and future backend readiness
Debt: `DEBT-0059`
Depends: `RND-007`, `RND-008`
Blocked By: Apple root package/app gate, signed bundle policy, and Mac mini
toolchain validation.
Scope: `src/renderer_metal_lab/*`, root `CMakeLists.txt`,
`tests/renderer_metal_lab/*`, `scripts/automation/apple-remote-build.ps1`,
`docs/modernization/build-inventory.md`
Goal:
Add a non-default `pp_renderer_metal_lab` target that proves the renderer-api
contract can map to Metal command encoders, textures, render passes, and
readback without entering the production app path.
Done Checks:
- Target is opt-in and excluded from production app/package builds.
- Apple remote validation can build the target on macOS and skip iOS device
execution unless a signed runner exists.
- Smoke tests cover tiny texture/render-pass/copy-readback behavior where a
headless Metal device is available.
- No OpenGL or Apple production package behavior changes.
Validation:
```powershell
powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.ps1 -Presets macos -Targets pp_renderer_metal_lab_tests
```
### UI-001 - Define UI Thread-Affinity And Mutation Contract
Status: Ready
Score: +2 hardening and future backend readiness
Debt: `DEBT-0003`, `DEBT-0063`
Scope: `src/ui_core/*`, `src/app_core/app_thread.*`,
`tests/ui_core/*`, `tests/app_core/app_thread_tests.cpp`,
`tools/pano_cli/*`
Goal:
Make UI safety explicit before broad retained UI migration: define which
operations are UI-thread-only, which may be posted from render/worker threads,
how checked node handles invalidate, how callbacks disconnect, and how layout
reload/destroy-during-callback mutations are sequenced.
Done Checks:
- `pp_ui_core` exposes a documented thread-affinity/mutation contract.
- Tests cover checked-handle invalidation, scoped callback disconnect,
destroy-during-callback, add/remove-during-dispatch, capture release, and
layout reload clear.
- `pp_app_core` app-thread plans reject or route unsafe cross-thread UI
mutations.
- `pano_cli plan-app-thread` exposes at least one unsafe-dispatch rejection
smoke.
Validation:
```powershell
ctest --preset desktop-fast --build-config Debug -R "pp_ui_core_(node_lifetime|overlay_lifetime)|pp_app_core_app_thread|pano_cli_plan_app_thread" --output-on-failure
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
```
### UI-002 - Migrate Next Retained Panel Family To Checked UI Handles
Status: Ready
Score: +2 legacy adapter retirement
Debt: `DEBT-0063`
Depends: `UI-001`
Scope: choose one family from `src/node_panel_layer.cpp`,
`src/node_panel_brush.cpp`, `src/node_panel_stroke.cpp`,
`src/node_dialog_open.cpp`, or `src/node_dialog_browse.cpp`, plus
`src/legacy_ui_overlay_services.*` and focused tests.
Goal:
Move one more retained UI family from raw `Node*`/manual destroy/callback
ownership to the checked-handle and scoped-callback model, preserving current
behavior while proving the migration pattern is repeatable.
Done Checks:
- Chosen family no longer uses open-coded root insertion, close callback
lifetime, outside-click release, or stale raw child pointers where a checked
handle/service exists.
- Mutation-during-callback and close/release tests cover the chosen family.
- `DEBT-0063` names the migrated family and the remaining families.
Validation:
```powershell
ctest --preset desktop-fast --build-config Debug -R "pp_ui_core_(node_lifetime|overlay_lifetime)" --output-on-failure
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter
```
### APP-001 - Add Render/UI Queue Race Regression Gate
Status: Ready
Score: +2 test and automation coverage
Debt: `DEBT-0003`, `DEBT-0017`
Depends: `UI-001`
Scope: `src/foundation/*`, `src/app_core/app_thread.*`,
`tests/foundation/*`, `tests/app_core/app_thread_tests.cpp`,
`tools/pano_cli/*`
Goal:
Add deterministic stress/regression coverage for render/UI task queues before
threading behavior is relied on by backend labs or safer UI adapters.
Done Checks:
- Tests cover nested dispatch, unique task replacement, shutdown drain,
cancellation/no-op after stop, exception-free error reporting, and worker to
UI/render handoff ordering.
- `stress` preset includes the longer queue scenario while `desktop-fast`
keeps a small deterministic subset.
- `pano_cli plan-app-thread` exposes queue scenarios as JSON smoke commands.
Validation:
```powershell
ctest --preset desktop-fast --build-config Debug -R "pp_foundation_task_queue|pp_app_core_app_thread|pano_cli_plan_app_thread" --output-on-failure
ctest --preset stress --build-config Debug -R "app_thread|task_queue" --output-on-failure
```
### PLT-010 - Gate Backend And UI Work On Platform Package Readiness
Status: Ready
Score: +2 platform and package parity
Debt: `DEBT-0004`, `DEBT-0011`, `DEBT-0059`
Scope: `scripts/automation/package-smoke.*`,
`scripts/automation/platform-build.*`, root `CMakeLists.txt`,
`docs/modernization/build-inventory.md`
Goal:
Make backend/UI modernization platform-sensitive by requiring named package or
package-readiness gates for Windows AppX, Apple bundles, Android standard,
Quest, Focus/Wave, Linux, and WebGL before backend lab or retained UI migration
work can claim broad readiness.
Done Checks:
- Package-readiness output identifies which backend/UI-sensitive platforms are
validated, blocked, or compile-only.
- Root CMake exposes a named target or documented command for each required
platform gate.
- Apple/iOS signed-bundle gaps and Windows AppX gaps remain debt-tracked until
real package builds exist.
- `docs/modernization/build-inventory.md` lists the commands as the current
gate for backend/UI roadmap work.
Validation:
```powershell
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -ReadinessOnly
ctest --preset desktop-fast --build-config Debug -R "panopainter_package_smoke_readiness_self_test|panopainter_platform_build_target_matrix_self_test" --output-on-failure
```
### STR-010 - Extract Remaining Draw Merge Composite Orchestration
### STR-016 - Extract Draw Merge Layer Composite Execution