788 lines
37 KiB
Markdown
788 lines
37 KiB
Markdown
# Modernization Task Tracker
|
|
|
|
Status: live
|
|
Last updated: 2026-06-13
|
|
|
|
This file turns the modernization roadmap into small, measurable work items.
|
|
The roadmap explains direction, the debt log explains why shortcuts remain, and
|
|
this tracker is the execution queue. Prefer closing one task here over adding a
|
|
new broad roadmap paragraph.
|
|
|
|
## Operating Rules
|
|
|
|
- Pick one `Ready` task at a time unless the user asks for planning only.
|
|
- Keep each slice small enough to validate and commit in one session.
|
|
- Do not claim percentage progress for "narrowed" debt. Points move only when a
|
|
task row is changed to `Done`.
|
|
- A task is `Done` only when its listed checks pass, the debt log is updated or
|
|
closed as applicable, and the roadmap/task score is updated.
|
|
- If a task proves too large, split it before editing code. The original task
|
|
stays `Ready` or becomes `Blocked` with the reason.
|
|
- After a verified task is committed and pushed, reset conversation context
|
|
before starting the next task when practical.
|
|
- When the user asks for subagents or delegation, follow
|
|
`docs/modernization/director-workflow.md` and keep each delegated task mapped
|
|
to a row in this tracker.
|
|
|
|
## Progress Scorecard
|
|
|
|
The current score is intentionally conservative. It should move in visible,
|
|
auditable steps rather than by subjective estimates.
|
|
|
|
| Area | Weight | Current | Progress Rule |
|
|
| --- | ---: | ---: | --- |
|
|
| Build and CMake ownership | 15 | 13 | Root CMake owns active source lists, app/tool targets, and retained package entrypoints. |
|
|
| Test and automation coverage | 15 | 9 | Headless, platform, package, and focused validation commands exist and are current. |
|
|
| Pure component behavior ownership | 15 | 8 | Behavior lives in `pp_*` components and is consumed by live adapters. |
|
|
| Legacy adapter retirement | 20 | 7 | `legacy_*_services` and singleton bridges are deleted or reduced to trivial composition. |
|
|
| Renderer boundary and OpenGL parity | 15 | 10 | Live render/export/readback paths execute through renderer interfaces with parity checks. |
|
|
| Platform and package parity | 10 | 6 | Required platforms have root CMake/package validation and injected platform services. |
|
|
| Hardening and future backend readiness | 10 | 2 | Edge, fuzz, golden, stress, and backend-lab gates exist for high-risk paths. |
|
|
| **Total** | **100** | **55** | Only completed tasks below may change this number. |
|
|
|
|
When updating `Current`, add a dated note under "Completed Task Log" with the
|
|
task id, points moved, validation command, and commit hash.
|
|
|
|
## Task States
|
|
|
|
| State | Meaning |
|
|
| --- | --- |
|
|
| `Ready` | Clear enough for an agent to execute. |
|
|
| `In progress` | Actively being changed in the current slice. |
|
|
| `Blocked` | Needs a user decision, missing toolchain, or a prior task. |
|
|
| `Done` | Validated, documented, committed, and pushed. |
|
|
|
|
## Ready Queue
|
|
|
|
### MT-001 - Adopt Measurable Task Tracking
|
|
|
|
Status: Done
|
|
Score: no score movement
|
|
Debt: none
|
|
Scope: `docs/modernization/tasks.md`, `docs/modernization/roadmap.md`
|
|
|
|
Steps:
|
|
|
|
- Add this tracker.
|
|
- Link it from the roadmap.
|
|
- Make the scorecard the source for percentage claims.
|
|
|
|
Done Checks:
|
|
|
|
- `docs/modernization/roadmap.md` points agents to this file.
|
|
- The tracker has task states, scoring rules, and at least one ready queue.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
git diff -- docs\modernization\roadmap.md docs\modernization\tasks.md
|
|
```
|
|
|
|
### ADP-001 - Remove History Bridge From Document Resize And Canvas Clear
|
|
|
|
Status: Done
|
|
Score: +1 legacy adapter retirement
|
|
Debt: `DEBT-0020`, `DEBT-0027`
|
|
Scope: `src/legacy_document_canvas_services.*`,
|
|
`src/app_core/document_resize.h`, `tests/app_core/document_resize_tests.cpp`,
|
|
related canvas-clear tests only
|
|
|
|
Goal:
|
|
|
|
Make document resize and canvas-clear execution consume app-core history
|
|
commands directly instead of routing through `legacy_history_services`.
|
|
|
|
Done Checks:
|
|
|
|
- `src/legacy_document_canvas_services.*` no longer includes
|
|
`legacy_history_services.h`.
|
|
- Resize still executes in order: resize, title update, history clear.
|
|
- Canvas clear still records undo and marks the document unsaved when a canvas
|
|
exists.
|
|
- `docs/modernization/debt.md` narrows or closes the affected removal condition.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_resize|pp_app_core_document_canvas|pano_cli_plan_document_resize|pano_cli_plan_canvas_clear" --output-on-failure
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
|
|
```
|
|
|
|
### ADP-002 - Remove History Bridge From Layer Operations
|
|
|
|
Status: Done
|
|
Score: +1 legacy adapter retirement
|
|
Debt: `DEBT-0021`
|
|
Scope: `src/legacy_document_layer_services.*`,
|
|
`src/app_core/document_layer.h`, `tests/app_core/document_layer_tests.cpp`
|
|
|
|
Goal:
|
|
|
|
Move layer add/remove/merge/clear/rename history side effects into tested
|
|
app-core execution plans so the live layer bridge no longer calls
|
|
`legacy_history_services`.
|
|
|
|
Done Checks:
|
|
|
|
- `src/legacy_document_layer_services.*` no longer includes
|
|
`legacy_history_services.h`.
|
|
- Layer operations still preserve undo/history behavior covered by
|
|
`pp_app_core_document_layer_tests`.
|
|
- `pano_cli plan-layer-operation`, `plan-layer-menu`, and
|
|
`plan-layer-rename` JSON remains compatible.
|
|
- `docs/modernization/debt.md` records the narrowed or closed layer-history
|
|
adapter dependency.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_layer|pano_cli_plan_layer" --output-on-failure
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
|
|
```
|
|
|
|
### ADP-003 - Remove History Bridge From Document Open And Session Save
|
|
|
|
Status: Done
|
|
Score: +1 legacy adapter retirement
|
|
Debt: `DEBT-0039`, `DEBT-0040`, `DEBT-0042`
|
|
Scope: `src/legacy_document_open_services.*`,
|
|
`src/legacy_document_session_services.*`,
|
|
`src/app_core/document_session.*`, `src/app_core/document_route.*`,
|
|
matching tests only
|
|
|
|
Goal:
|
|
|
|
Make document-open, close, save, save-before-workflow, Save As, and Save Version
|
|
history effects explicit app-core outputs instead of direct
|
|
`legacy_history_services` calls in the live bridges.
|
|
|
|
Done Checks:
|
|
|
|
- `src/legacy_document_open_services.*` and
|
|
`src/legacy_document_session_services.*` no longer include
|
|
`legacy_history_services.h`.
|
|
- Existing dirty-document, save-before, new-document, Save As, and Save Version
|
|
plans preserve their JSON contracts.
|
|
- The debt log is updated for every debt id listed above.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_route|pp_app_core_document_session|pano_cli_plan_open_route|pano_cli_simulate_app_session|pano_cli_plan_document_file|pano_cli_plan_document_version" --output-on-failure
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
|
|
```
|
|
|
|
### ADP-004 - Make Dialog Creation A UI Factory Boundary
|
|
|
|
Status: Done
|
|
Score: +2 legacy adapter retirement
|
|
Debt: `DEBT-0058`, `DEBT-0063`
|
|
Scope: `src/legacy_app_dialog_services.*`,
|
|
`src/legacy_ui_overlay_services.*`, `src/app_dialogs.cpp`,
|
|
`src/app_core/app_dialog.h`, dialog tests only
|
|
|
|
Goal:
|
|
|
|
Keep app-core dialog metadata pure, but move retained
|
|
`NodeProgressBar`/`NodeMessageBox`/`NodeInputBox` construction behind one
|
|
`pp_panopainter_ui` or retained UI factory function. `App` should ask for a
|
|
dialog object through an interface instead of knowing individual node creation
|
|
details.
|
|
|
|
Done Checks:
|
|
|
|
- `App::show_progress`, `App::message_box`, and `App::input_box` still preserve
|
|
captions, cancel behavior, and keyboard behavior.
|
|
- New factory path has focused tests or existing `pp_app_core_app_dialog_tests`
|
|
plus a smoke command proving the live adapter still builds.
|
|
- The debt log states exactly which raw-node lifetime hazards remain.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_app_core_app_dialog|pano_cli_plan_app_dialog" --output-on-failure
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
|
|
```
|
|
|
|
### ADP-005 - Convert One Popup/Dialog Family To Checked Overlay Lifetime
|
|
|
|
Status: Done
|
|
Score: +2 legacy adapter retirement
|
|
Debt: `DEBT-0063`
|
|
Scope: choose exactly one family from `src/node_dialog_open.cpp`,
|
|
`src/node_dialog_browse.cpp`, `src/node_panel_quick.cpp`,
|
|
`src/node_panel_stroke.cpp`, or `src/node_combobox.cpp`, plus
|
|
`src/legacy_ui_overlay_services.*`
|
|
|
|
Goal:
|
|
|
|
Adopt `pp_ui_core` overlay lifetime semantics for one retained popup/dialog
|
|
family before trying to rewrite all retained UI nodes.
|
|
|
|
Done Checks:
|
|
|
|
- The chosen family no longer owns open-coded root insertion, outside-click
|
|
release, close callback wiring, or destroy-during-callback behavior.
|
|
- Existing UI behavior is preserved.
|
|
- Tests cover missing root/template handling and close/release behavior for the
|
|
chosen family.
|
|
- The debt log names the completed family and the remaining families.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_ui_core_overlay_lifetime|pp_ui_core_node_lifetime" --output-on-failure
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter
|
|
```
|
|
|
|
### RND-001 - Make Pure Equirectangular Export The Primary Success Path
|
|
|
|
Status: Done
|
|
Score: +2 renderer boundary and OpenGL parity
|
|
Debt: `DEBT-0010`, `DEBT-0036`, `DEBT-0043`
|
|
Scope: `src/legacy_document_export_services.*`,
|
|
`src/app_core/document_export.*`, `src/paint_renderer/compositor.*`,
|
|
`tests/app_core/document_export_tests.cpp`,
|
|
`tests/paint_renderer/compositor_tests.cpp`
|
|
|
|
Goal:
|
|
|
|
For payload-complete snapshots, live PNG/JPEG equirectangular export should
|
|
complete through the pure document/paint-renderer writer. Retained
|
|
`Canvas::export_equirectangular*` should run only for unsupported Web,
|
|
incomplete-readback, or writer-failure fallbacks.
|
|
|
|
Done Checks:
|
|
|
|
- Export route reports whether the pure writer was used or why fallback was
|
|
required.
|
|
- Tests cover pure-writer success and each fallback reason.
|
|
- Live bridge does not call retained equirectangular export after pure-writer
|
|
success.
|
|
- The debt log narrows retained equirectangular export execution.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_export|pp_paint_renderer_compositor|pano_cli_plan_export_snapshot_route|pano_cli_simulate_document_export" --output-on-failure
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
|
|
```
|
|
|
|
### RND-002 - Make Pure Layer And Animation Collection Export Primary
|
|
|
|
Status: Done
|
|
Score: +2 renderer boundary and OpenGL parity
|
|
Debt: `DEBT-0010`, `DEBT-0036`, `DEBT-0043`
|
|
Scope: `src/legacy_document_export_services.*`,
|
|
`src/app_core/document_export.*`, `src/paint_renderer/compositor.*`,
|
|
collection export tests only
|
|
|
|
Goal:
|
|
|
|
For payload-complete snapshots, live layer and animation-frame collection export
|
|
should complete through the pure collection writer. Retained
|
|
`Canvas::export_layers*` and `Canvas::export_anim_frames*` should run only for
|
|
unsupported Web, incomplete-readback, or writer-failure fallbacks.
|
|
|
|
Done Checks:
|
|
|
|
- Collection export route reports pure-writer success versus fallback reason.
|
|
- Tests cover layer collection, animation-frame collection, and fallback.
|
|
- The debt log narrows retained collection export execution.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_export|pp_paint_renderer_compositor|pano_cli_plan_export_snapshot_route" --output-on-failure
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
|
|
```
|
|
|
|
### RND-003 - Replace Depth Export Readiness With Pure Depth Export Execution
|
|
|
|
Status: Done
|
|
Score: +3 renderer boundary and OpenGL parity
|
|
Debt: `DEBT-0010`, `DEBT-0036`, `DEBT-0043`
|
|
Scope: `src/paint_renderer/compositor.*`,
|
|
`src/app_core/document_export.*`, `src/legacy_document_export_services.*`,
|
|
depth tests only
|
|
|
|
Goal:
|
|
|
|
Turn the current pure depth export render plan into actual payload generation
|
|
for payload-complete snapshots, then write image/depth payloads through the
|
|
existing app-core two-payload writer before falling back to retained
|
|
`Canvas::export_depth*`.
|
|
|
|
Done Checks:
|
|
|
|
- Pure depth export produces deterministic image and depth payloads for a
|
|
payload-complete snapshot.
|
|
- Retained depth export runs only for unsupported targets, incomplete readback,
|
|
or writer failure.
|
|
- Tests cover malformed depth target inputs and byte-size validation.
|
|
- The debt log narrows depth export readback/execution.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_export|pp_paint_renderer_compositor|pano_cli_plan_export_snapshot_route" --output-on-failure
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pano_cli
|
|
```
|
|
|
|
### RND-004 - Add First Desktop GPU Golden Gate
|
|
|
|
Status: Done
|
|
Score: +2 hardening and future backend readiness
|
|
Debt: `DEBT-0036`
|
|
Scope: `tests/`, `CMakeLists.txt`, renderer test helpers only
|
|
|
|
Goal:
|
|
|
|
Create the first non-default `desktop-gpu` golden/readback test that validates
|
|
one OpenGL output against a deterministic fixture. Keep it opt-in so headless
|
|
agents are not blocked.
|
|
|
|
Done Checks:
|
|
|
|
- `ctest --preset desktop-gpu --build-config Debug` has at least one real test.
|
|
- The test is skipped with a clear message when no GPU/context is available.
|
|
- The roadmap and debt log describe what the golden covers and what remains.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-gpu --build-config Debug --output-on-failure
|
|
ctest --preset desktop-fast --build-config Debug -R "pp_renderer_gl|pp_paint_renderer" --output-on-failure
|
|
```
|
|
|
|
### PLT-001 - Split Apple Picker/Browse Service From Legacy Platform Adapter
|
|
|
|
Status: Done
|
|
Score: +2 platform and package parity
|
|
Debt: `DEBT-0017`, `DEBT-0051`, `DEBT-0055`
|
|
Scope: `src/platform_legacy/legacy_platform_services.*`, new
|
|
`src/platform_apple/*` files if needed, `CMakeLists.txt`, platform API tests
|
|
|
|
Goal:
|
|
|
|
Move macOS/iOS document browse roots, file picking, directory picking, and
|
|
display-path formatting out of the catch-all legacy platform adapter and into a
|
|
named Apple platform service boundary.
|
|
|
|
Done Checks:
|
|
|
|
- `src/platform_legacy/legacy_platform_services.*` no longer owns Apple
|
|
browse/picker policy.
|
|
- Apple compile validation still passes through the remote build script.
|
|
- The debt log narrows Apple platform shell extraction.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --output-on-failure
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.ps1 -Presets macos,ios-simulator,ios-device
|
|
```
|
|
|
|
### PLT-002 - Split Web Export/Storage Policy From Legacy Platform Adapter
|
|
|
|
Status: Done
|
|
Score: +2 platform and package parity
|
|
Debt: `DEBT-0050`, `DEBT-0053`, `DEBT-0057`
|
|
Scope: `src/platform_legacy/legacy_platform_services.*`, new
|
|
`src/platform_web/*` files if needed, `src/platform_api/*`, platform tests
|
|
|
|
Goal:
|
|
|
|
Move WebGL exported-image publishing, persistent-storage flushing,
|
|
prepared-file handoff, and default canvas resolution out of the catch-all
|
|
legacy platform adapter into a named Web platform service boundary.
|
|
|
|
Done Checks:
|
|
|
|
- Web policy is injectable through `pp_platform_api`.
|
|
- The legacy adapter no longer owns Web default canvas resolution or storage
|
|
flush policy.
|
|
- Package-smoke readiness still reports Web blockers explicitly.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --output-on-failure
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -ReadinessOnly
|
|
```
|
|
|
|
### DEP-001 - Remove Generated fmt Overlay
|
|
|
|
Status: Done
|
|
Score: +1 build and CMake ownership
|
|
Debt: `DEBT-0062`
|
|
Scope: `CMakeLists.txt`, `cmake/`, `vcpkg.json`, `libs/fmt` or package wiring
|
|
|
|
Goal:
|
|
|
|
Use a supported fmt package or update the vendored fmt release so VS 2026 no
|
|
longer needs a generated `format.h` overlay.
|
|
|
|
Done Checks:
|
|
|
|
- No build-tree fmt header overlay is generated.
|
|
- `DEBT-0062` is closed.
|
|
- Windows app and at least one focused component test build pass.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter pp_platform_api_tests
|
|
ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --output-on-failure
|
|
```
|
|
|
|
### DEP-002 - Remove Generated nanort Overlay
|
|
|
|
Status: Done
|
|
Score: +1 build and CMake ownership
|
|
Debt: `DEBT-0060`
|
|
Scope: retained Android package CMake, `libs/nanort`, grid/lightmap dependency
|
|
wiring
|
|
Goal:
|
|
|
|
Update, replace, or isolate `nanort` so Android package builds do not generate
|
|
a patched vendor overlay.
|
|
|
|
Done Checks:
|
|
|
|
- Android retained package CMake no longer generates a patched `nanort.h`.
|
|
- `DEBT-0060` is closed.
|
|
- Standard Android retained package validation passes.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\android-legacy-package-build.ps1 -Packages standard
|
|
cmake --build --preset windows-msvc-default --config Debug --target PanoPainter
|
|
```
|
|
|
|
## Blocked Or Later Queue
|
|
|
|
These are real goals, but they should not be picked until prerequisite tasks
|
|
above have reduced risk.
|
|
|
|
### LATER-001 - Replace OpenVR With OpenXR
|
|
|
|
Status: Blocked
|
|
Score: +3 platform and package parity
|
|
Debt: `DEBT-0061`
|
|
Blocked By: OpenXR package decision and runtime availability
|
|
|
|
Done Checks:
|
|
|
|
- OpenXR SDK/package target exists.
|
|
- Windows platform service can start/stop desktop XR without OpenVR.
|
|
- `libs/openvr` and `openvr_api.dll` deployment are removed.
|
|
- `DEBT-0061` is closed.
|
|
|
|
### LATER-002 - Remove Catch2 Harness Debt
|
|
|
|
Status: Blocked
|
|
Score: +2 test and automation coverage
|
|
Debt: `DEBT-0005`
|
|
Blocked By: vcpkg/toolchain reliability across Windows and headless presets
|
|
|
|
Done Checks:
|
|
|
|
- Existing local test harness is replaced or permanently justified.
|
|
- Catch2 tests run through `desktop-fast` and vcpkg headless presets.
|
|
- `DEBT-0005` is closed.
|
|
|
|
### LATER-003 - Live Stroke Rasterization Through Renderer Services
|
|
|
|
Status: Ready
|
|
Score: +5 renderer boundary and OpenGL parity
|
|
Debt: `DEBT-0036`
|
|
|
|
Done Checks:
|
|
|
|
- Live stroke rasterization, dual-brush compositing, and pattern feedback choose
|
|
paths through renderer services.
|
|
- OpenGL output parity is covered by golden/readback tests.
|
|
- Retained stroke OpenGL execution is deleted or isolated as an OpenGL backend
|
|
implementation.
|
|
|
|
Progress Notes:
|
|
|
|
- 2026-06-13: `Canvas::draw_merge()` now routes per-plane merge-target clear,
|
|
blend-state gating, and optional checkerboard prepass through
|
|
`execute_legacy_canvas_draw_merge_plane_setup(...)`; per-layer iteration,
|
|
temporary-stroke branches, and concrete framebuffer ownership remain local to
|
|
`Canvas`. Next slice should target another narrow draw-merge execution seam
|
|
without reopening landed plane-setup, temporary-composite, layer-blend,
|
|
final-plane, or texture-alpha helpers.
|
|
- 2026-06-13: `Canvas::draw_merge()` now routes the standard per-layer
|
|
texture-alpha pass through
|
|
`execute_legacy_canvas_draw_merge_layer_texture(...)`; temporary-stroke
|
|
branches, per-plane iteration, and concrete RTT ownership remain local to
|
|
`Canvas`. Next slice should target another narrow draw-merge execution seam
|
|
without reopening landed temporary-composite, layer-blend, final-plane, or
|
|
texture-alpha helpers.
|
|
- 2026-06-13: `pp_paint_renderer_stroke_execution_tests` now also covers
|
|
retained frame-plan assembly for previous-sample projection mode and zoom
|
|
scaling. Next slice should target the remaining preview/Canvas stroke
|
|
execution seam or another narrow renderer boundary without reopening the
|
|
landed stroke-frame planner coverage.
|
|
- 2026-06-13: `NodeStrokePreview` live-pass orchestration now routes through
|
|
`execute_legacy_stroke_preview_live_pass(...)`, and
|
|
`pp_paint_renderer_stroke_execution_tests` now covers live-pass clear,
|
|
traversal, and final copy ordering. Next slice should target the remaining
|
|
preview or Canvas stroke execution seam without reopening the landed live-pass
|
|
helper.
|
|
- 2026-06-13: `NodeStrokePreview::draw_stroke_immediate()` now routes retained
|
|
preview feedback/material/composite planning plus stroke-shader uniform
|
|
assembly through `plan_legacy_node_stroke_preview_pass_orchestration(...)`;
|
|
compositor coverage now locks destination-feedback fallback, composite-slot
|
|
intent, and the retained pattern/dual shader-uniform handoff. The preview
|
|
node still owns brush object mutation, retained `Stroke` population, and the
|
|
concrete GL pass callbacks. Next slice should target another narrow preview
|
|
execution seam without reopening the landed preview setup, mix, pass-sequence,
|
|
or final-composite helpers.
|
|
- 2026-06-13: `NodeStrokePreview::draw_stroke_immediate()` now routes preview
|
|
stroke max-size fallback, dual-preview max-size derivation, pattern-scale
|
|
flips, and Bezier preview-point generation through
|
|
`plan_legacy_node_stroke_preview_stroke_setup(...)`; compositor coverage now
|
|
also locks the retained stroke-setup curve/pressure intent and
|
|
pass-sequence request-validation short-circuit behavior. The preview node
|
|
still owns brush object mutation, camera wiring, retained `Stroke`
|
|
population, and live GL execution. Next slice should target the remaining
|
|
higher-level preview pass orchestration seam without reopening landed
|
|
sample, mix, pass-sequence, or final-composite helpers.
|
|
- 2026-06-13: `Canvas::draw_merge()` per-layer blend composite now routes
|
|
merge-RTT unbind, shader setup, optional destination-copy feedback, draw,
|
|
and cleanup ordering through
|
|
`execute_legacy_canvas_draw_merge_layer_blend(...)`; temporary-stroke
|
|
branch selection, layer iteration, and final merged-plane redraw ownership
|
|
remain local to `Canvas`. Next slice should target the remaining end-of-plane
|
|
merged-texture copy/grid/final-redraw seam or another similarly narrow final
|
|
composite boundary without reopening landed temporary-composite or
|
|
per-layer blend helpers.
|
|
- 2026-06-13: `Canvas::draw_merge()` end-of-plane merged-texture copy,
|
|
optional checkerboard redraw, and final merged-texture composite ordering now
|
|
route through `execute_legacy_canvas_draw_merge_final_plane_composite(...)`;
|
|
per-plane iteration and concrete framebuffer, sampler, texture, and draw
|
|
callbacks remain local to `Canvas`. Next slice should target another narrow
|
|
retained draw-merge boundary without reopening landed temporary-composite,
|
|
layer-blend, or final-plane helpers.
|
|
- 2026-06-13: `Canvas::draw_merge()` erase live temporary-stroke composite now
|
|
routes retained setup, sampler bind, texture bind, draw, and texture unbind
|
|
ordering through `execute_legacy_canvas_stroke_temporary_composite(...)`;
|
|
both live temporary composite branches now share the same retained execution
|
|
helper while `Canvas` keeps only concrete GL object callbacks and broader
|
|
final composite ownership. Next slice should target the remaining final
|
|
composite seam without reopening landed sample, mix, dirty, or framebuffer
|
|
helpers.
|
|
- 2026-06-13: `NodeStrokePreview::stroke_draw_mix()` now routes retained
|
|
mix-pass shader setup plus framebuffer/state/input/draw ordering through
|
|
`execute_legacy_node_stroke_preview_mix_pass(...)`, with compositor coverage
|
|
locking the retained callback order and shader-plan handoff. The preview node
|
|
keeps only the concrete GL save/restore, texture-object bind, and plane-draw
|
|
callbacks. Next slice should target another retained preview or canvas stroke
|
|
seam without reopening the landed preview sample, material-planning,
|
|
pass-sequence, or final-composite helpers.
|
|
- 2026-06-13: `NodeStrokePreview::draw_stroke_immediate()` now routes
|
|
dual-pass/background/main-pass/final-composite/copy-back ordering through
|
|
`execute_legacy_node_stroke_preview_pass_sequence(...)`; the remaining local
|
|
preview ownership is concentrated around `stroke_draw_mix()` setup/execution.
|
|
Next slice should target that final mix-pass setup/execution seam without
|
|
reopening landed sample, binding, material-planning, or final-composite
|
|
helpers.
|
|
- 2026-06-13: `Canvas::draw_merge()` non-erase live temporary-stroke
|
|
composite ordering now routes through
|
|
`execute_legacy_canvas_stroke_temporary_composite(...)`; erase-path and
|
|
broader final composite ownership still remain local to `Canvas`. Next slice
|
|
should target the erase temporary composite branch or another similarly
|
|
narrow final composite seam without reopening landed sample, mix, dirty, or
|
|
framebuffer helpers.
|
|
- 2026-06-13: `Canvas::stroke_draw_samples()` now routes face-indexed
|
|
destination bind/copy/unbind and brush upload/draw through
|
|
`execute_legacy_canvas_stroke_face_sample_polygon(...)`; the retained sample
|
|
executor now owns the face-aware dispatch contract while `Canvas` keeps only
|
|
the concrete GL object callbacks. Next slice should target any remaining
|
|
final temporary-texture composite setup without reopening landed sample,
|
|
mix, sampler, dirty, face, or pad helpers.
|
|
- 2026-06-13: `pp_paint_renderer_stroke_execution_tests` now also covers
|
|
direct retained frame-sample callback ordering plus
|
|
`execute_legacy_canvas_stroke_frame_samples_with_dirty_tracking(...)`
|
|
timing/state semantics, including pre-update dirty visibility and
|
|
`previous_pass_dirty_box` override behavior. Next test slice should target
|
|
the next header-level preview live sample ordering surface without reopening
|
|
production files.
|
|
- 2026-06-13: `Canvas::stroke_draw_mix()` now routes visible-plane filtering,
|
|
retained sampler/texture-slot binding, and final plane draw ordering through
|
|
`execute_legacy_canvas_stroke_mix_pass(...)`; mixer framebuffer/state setup
|
|
and per-plane shader material/MVP preparation remain local to `Canvas`. Next
|
|
slice should target the remaining `stroke_draw_samples()` callback body or
|
|
any final temporary-texture composite setup without reopening landed
|
|
sample, sampler, dirty, face, or pad helpers.
|
|
- 2026-06-13: `pp_paint_renderer_stroke_execution_tests` now also covers
|
|
retained preview background capture ordering, final composite ordering, and
|
|
preview texture-copy bind-before-copy behavior via
|
|
`legacy_canvas_stroke_preview_services.h`. Next test slice should target the
|
|
next header-level preview live sample or mix-pass ordering surface without
|
|
reopening production files.
|
|
- 2026-06-13: `Canvas::stroke_draw_samples()` now routes polygon
|
|
triangulation, sample-point assembly, and the retained destination-copy /
|
|
upload / draw helper handoff through
|
|
`execute_legacy_canvas_stroke_sample_polygon(...)`; direct GL callback
|
|
wiring and the remaining live draw ownership stay local to `Canvas`. Next
|
|
slice should target the remaining callback body or final temporary-texture
|
|
composite setup without reopening the landed sampler, dirty, face, or pad
|
|
helpers.
|
|
- 2026-06-13: `NodeStrokePreview::stroke_draw_mix()` now routes mixer
|
|
framebuffer bind/unbind, viewport/scissor/blend state, texture-slot binding,
|
|
and final plane draw through one local helper; material planning and shader
|
|
uniform setup remain local to the preview node. Next slice should target the
|
|
remaining mix-pass material/setup orchestration without reopening the landed
|
|
preview live-pass, binding, sample, or final composite helpers.
|
|
- 2026-06-13: `NodeStrokePreview::stroke_draw_mix()` now routes retained
|
|
mix-pass material planning plus composite/pattern/dual uniform payload
|
|
assembly through `plan_legacy_node_stroke_preview_mix_pass(...)`, with
|
|
compositor coverage locking the retained preview mix adapter semantics for
|
|
composite-pass patterning and dual state. Mixer framebuffer ownership,
|
|
retained shader execution, texture binding, and final draw/copy ordering
|
|
remain local to the preview node. Next slice should target the remaining
|
|
mix-pass execution ownership without reopening the landed preview live-pass,
|
|
binding, sample, or final composite helpers.
|
|
- 2026-06-13: `pp_paint_renderer_stroke_execution_tests` now also covers
|
|
retained texture-dispatch activation order and sampler-dispatch routing
|
|
across brush tip, destination, pattern, and mixer helper inputs. Next test
|
|
slice should extend the dedicated lane into frame-sample loop ordering or
|
|
preview-side retained helper coverage.
|
|
- 2026-06-13: Added `pp_paint_renderer_stroke_execution_tests` as a dedicated
|
|
retained stroke execution-helper target covering texture-input binding order,
|
|
sample destination-copy behavior, live-pass face-framebuffer dirty tracking,
|
|
and pad-face destination-copy behavior. Next test slice should extend this
|
|
target toward the newer sampler-dispatch helpers or preview-side retained
|
|
execution helpers.
|
|
- 2026-06-13: `Canvas::stroke_draw` live-pass sampler bind/unbind plus
|
|
semantic texture-input dispatch now routes through retained stroke execution
|
|
helpers; concrete GL object mapping, framebuffer ownership, shader timing,
|
|
and final draw execution remain local to `Canvas`. Next slice should target
|
|
the remaining live draw execution boundary inside `stroke_draw_samples()` or
|
|
the final temporary-texture composite setup without reopening the landed
|
|
dirty, face-framebuffer, pad, or texture-intent helpers.
|
|
- 2026-06-13: `NodeStrokePreview::stroke_draw_samples()` now routes
|
|
destination bind/unbind, framebuffer copy callback wrapping, sample-point
|
|
assembly, and brush-vertex upload/draw through one local helper; mixer-pass
|
|
state execution and higher-level pass orchestration remain local to the
|
|
preview node. Next slice should target the remaining mixer-pass state/copy
|
|
ordering without reopening the landed preview live-pass, binding, or final
|
|
composite helpers.
|
|
- 2026-06-13: `Canvas::stroke_draw` main, pad, and dual live-pass
|
|
texture-input binding/unbinding intent now routes through retained stroke
|
|
execution helpers; sampler binding, concrete GL object mapping, framebuffer
|
|
ownership, and final draw execution remain local to `Canvas`. Next slice
|
|
should target the remaining sampler binding/teardown or the direct
|
|
semantic-input-to-GL mapping callbacks without reopening the landed dirty,
|
|
face-framebuffer, or pad helpers.
|
|
- 2026-06-13: `NodeStrokePreview::draw_stroke_immediate()` live-pass sampler
|
|
binding, dual/main pass texture binding, checkerboard/background capture
|
|
wrapping, and final preview copy-back now route through named local helpers;
|
|
mixer state execution and per-sample GL ordering remain local to the preview
|
|
node. Next slice should target the remaining mixer-pass state/copy ordering
|
|
or sample-pass destination callback wrapping without reopening the landed
|
|
preview live-pass or final-composite helpers.
|
|
- 2026-06-13: `NodeStrokePreview::draw_stroke_immediate()` dual-pass and
|
|
main-pass frame-loop execution plus full-frame copy-back now route through
|
|
shared local helpers; checkerboard/background capture ordering, texture-unit
|
|
binding, mixer ownership, and final composite semantics remain local to the
|
|
preview node. Next slice should target background/final-copy helpers or
|
|
pass-level texture binding without reopening the new preview composite
|
|
helper.
|
|
- 2026-06-13: `Canvas::stroke_draw` main and dual live-pass per-face
|
|
framebuffer begin/end execution plus pad-face array assembly now route
|
|
through `legacy_canvas_stroke_execution_services.h`; shader activation
|
|
timing, texture/sampler binding, framebuffer ownership, and final draw
|
|
execution remain local to `Canvas`. Next slice should target the remaining
|
|
pass-level texture binding or final composite setup without reopening the
|
|
newer pad, dirty, or commit helpers.
|
|
- 2026-06-13: `Canvas::stroke_draw` current and dual stroke per-face
|
|
framebuffer/sample callback ordering now routes through
|
|
`legacy_canvas_stroke_execution_services.h`; framebuffer ownership, shader
|
|
uniform timing, sampler/texture binding, and draw execution remain local to
|
|
Canvas. Next slice should target the remaining per-face retained state around
|
|
sample execution without reopening the new pad-pass, dirty-mutation, or
|
|
commit executors.
|
|
- 2026-06-13: `Canvas::stroke_draw` current and dual stroke dirty-box mutation
|
|
now routes through `legacy_canvas_stroke_execution_services.h`; framebuffer
|
|
binding, shader uniform timing, sampler/texture binding, and draw execution
|
|
remain local to Canvas. Next slice should wrap the retained per-face
|
|
framebuffer/sample callback ordering without rewriting the new pad-pass or
|
|
commit executors.
|
|
- 2026-06-13: `Canvas::stroke_commit` now routes retained commit input
|
|
texture/sampler binding, erase/composite draw dispatch, committed-copy, and
|
|
dilate draw through `legacy_canvas_stroke_commit_services.h`; history
|
|
readback, `ActionStroke` population, and layer dirty-box mutation remain
|
|
local to Canvas.
|
|
- 2026-06-13: `pp_paint_renderer` owns tested Canvas stroke commit sequencing
|
|
and commit texture slot intent. Next slice should wire
|
|
`legacy_canvas_stroke_commit_services.h` into `Canvas::stroke_commit` while
|
|
keeping history/layer mutation local.
|
|
|
|
### LATER-004 - Remove Catch-All Platform Legacy Adapter
|
|
|
|
Status: Blocked
|
|
Score: +5 platform and package parity
|
|
Debt: `DEBT-0017`
|
|
Blocked By: Apple/Web split tasks and per-platform package validation
|
|
|
|
Done Checks:
|
|
|
|
- `src/platform_legacy/legacy_platform_services.*` is deleted or contains only
|
|
compile-time unsupported stubs with debt entries.
|
|
- Windows, Apple, Android, Linux, and Web platform services are named targets.
|
|
- Platform-build and package-smoke report explicit pass/fail per platform.
|
|
|
|
## Completed Task Log
|
|
|
|
| Date | Task | Score Change | Validation | Commit |
|
|
| --- | --- | ---: | --- | --- |
|
|
| 2026-06-12 | RND-004 | +2 hardening and future backend readiness | `ctest --preset desktop-gpu --build-config Debug --output-on-failure`; `ctest --preset desktop-fast --build-config Debug -R "pp_renderer_gl\|pp_paint_renderer" --output-on-failure` | e37b2929 |
|
|
| 2026-06-12 | DEP-002 | +1 build and CMake ownership | `powershell -ExecutionPolicy Bypass -File scripts\automation\android-legacy-package-build.ps1 -Packages standard` | 648404ee |
|
|
| 2026-06-12 | RND-002 | +2 renderer boundary and OpenGL parity | `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_export\|pp_paint_renderer_compositor\|pano_cli_plan_export_snapshot_route\|pano_cli_simulate_document_export" --output-on-failure` | 46fb8ef |
|
|
| 2026-06-12 | RND-001 | +2 renderer boundary and OpenGL parity | `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_export\|pp_paint_renderer_compositor\|pano_cli_plan_export_snapshot_route\|pano_cli_simulate_document_export" --output-on-failure` | 46fb8ef |
|
|
| 2026-06-12 | ADP-004 | +2 legacy adapter retirement | VS-bundled CMake build of `pp_app_core_app_dialog_tests` and `pano_cli`; `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_app_dialog\|pano_cli_plan_app_dialog" --output-on-failure` | 46fb8ef |
|
|
| 2026-06-12 | PLT-001 | +2 platform and package parity | VS-bundled CMake build of `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --output-on-failure`; Apple remote build blocked by unpublished fmt submodule pointer before DEP-001 correction | 46fb8ef |
|
|
| 2026-06-12 | RND-003 | +3 renderer boundary and OpenGL parity | VS-bundled CMake build of `pp_paint_renderer_compositor_tests`, `pp_app_core_document_export_tests`, and `pano_cli`; `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_export\|pp_paint_renderer_compositor\|pano_cli_plan_export_snapshot_route" --output-on-failure` | 46fb8ef |
|
|
| 2026-06-12 | DEP-001 | +1 build and CMake ownership | VS-bundled CMake build of `PanoPainter` and `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --output-on-failure` | 46fb8ef |
|
|
| 2026-06-12 | ADP-003 | +1 legacy adapter retirement | `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_route\|pp_app_core_document_session\|pano_cli_plan_open_route\|pano_cli_simulate_app_session\|pano_cli_plan_document_file\|pano_cli_plan_document_version" --output-on-failure` | 34a9e910 |
|
|
| 2026-06-12 | PLT-002 | +2 platform and package parity | `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests --output-on-failure`; `powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -ReadinessOnly`; `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_layer\|pano_cli_plan_layer\|pp_platform_api_tests" --output-on-failure` | 8cd38401 |
|
|
| 2026-06-12 | ADP-002 | +1 legacy adapter retirement | `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_layer\|pano_cli_plan_layer" --output-on-failure`; `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_layer\|pano_cli_plan_layer\|pp_platform_api_tests" --output-on-failure` | ae242852 |
|
|
| 2026-06-12 | ADP-001 | +1 legacy adapter retirement | `ctest --preset desktop-fast --build-config Debug -R "pp_app_core_document_resize\|pp_app_core_document_canvas\|pano_cli_plan_document_resize\|pano_cli_plan_canvas_clear" --output-on-failure`; `powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pano_cli -TestRegex "pp_app_core\|pano_cli_plan"` | e489b1e2 |
|
|
| 2026-06-12 | MT-001 | 0 | `git diff -- docs\modernization\roadmap.md docs\modernization\tasks.md` | same docs slice |
|
|
|
|
## Task Template
|
|
|
|
Use this shape when adding a new task:
|
|
|
|
````markdown
|
|
### AREA-000 - Imperative Task Name
|
|
|
|
Status: Ready
|
|
Score: +N scorecard area
|
|
Debt: `DEBT-0000`
|
|
Scope: exact files or directories
|
|
|
|
Goal:
|
|
|
|
One paragraph describing the behavior or ownership change.
|
|
|
|
Done Checks:
|
|
|
|
- Binary, grep-able, or testable condition.
|
|
- Debt log update condition.
|
|
- Validation condition.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
command
|
|
```
|
|
````
|