721 lines
24 KiB
Markdown
721 lines
24 KiB
Markdown
# Modernization Task Tracker
|
|
|
|
Status: live
|
|
Last updated: 2026-06-17
|
|
|
|
This file is the active execution queue. It is written for a coordinator that
|
|
can assign bounded packets to smaller parallel workers. Completed and stale
|
|
history belongs in `docs/modernization/tasks-done.md`, not here.
|
|
|
|
## Operating Rules
|
|
|
|
- Prioritize working-app ownership transfer over planners, CLI commands,
|
|
package-only cleanup, or test-only work.
|
|
- Every coding task must remove or narrow a real retained dependency, hotspot,
|
|
unsafe ownership path, or thread/runtime ambiguity.
|
|
- Tests are validation and guardrails. A task that only adds tests is not a P0
|
|
modernization slice unless it directly enables a blocked ownership move.
|
|
- Do not broaden worker scopes. If a task crosses file boundaries, split it
|
|
into worker packets with disjoint write scopes and integrate centrally.
|
|
- No new `App::I`, `Canvas::I`, owning raw `Node*`, detached worker, direct GL
|
|
resource dependency, or platform SDK dependency may be introduced in moved
|
|
code.
|
|
- Raw pointers may remain only as documented non-owning implementation details
|
|
backed by a checked owner, handle, scoped connection, or explicit lifetime
|
|
contract.
|
|
- Preserve current app behavior first. UI appearance, file formats, brush
|
|
behavior, platform behavior, and rendering output are not to be redesigned in
|
|
modernization slices.
|
|
- Use CMake source ownership as the progress signal. Shrinking
|
|
`PP_PANOPAINTER_*` and `PP_LEGACY_*` ownership matters more than adding new
|
|
helpers around the same retained code.
|
|
|
|
## Current Audit Snapshot
|
|
|
|
Validation performed during the 2026-06-17 review:
|
|
|
|
- `python scripts/dev/check_component_boundaries.py`: passed.
|
|
- `python scripts/dev/check_renderer_api_contract.py`: passed.
|
|
|
|
Key facts:
|
|
|
|
- Pure component boundaries currently pass their static checks.
|
|
- Remaining architectural risk is concentrated in the working app, retained
|
|
app/UI/canvas targets, singleton reach, raw node ownership, and direct GL
|
|
resource usage.
|
|
- `PP_PANOPAINTER_APP_SOURCES`: 47 files, about 9620 lines.
|
|
- `PP_PANOPAINTER_UI_SOURCES`: 52 files, about 9051 lines.
|
|
- `PP_LEGACY_PAINT_DOCUMENT_SOURCES`: 22 files, about 6277 lines.
|
|
- `PP_LEGACY_APP_SOURCES`: 26 files, about 4711 lines.
|
|
- `PP_LEGACY_UI_CORE_SOURCES`: 32 files, about 4304 lines.
|
|
- `App::I` still appears hundreds of times in retained app/canvas/UI/resource
|
|
code.
|
|
- `Canvas::I` still appears hundreds of times in retained canvas modes, panels,
|
|
and workflow bridges.
|
|
- Raw `Node*` and callback captures remain a dominant UI lifetime risk.
|
|
- `RTT`, `Texture2D`, `Shape`, `Shader`, `Font`, and `CanvasLayer` still route
|
|
render work through `App::I` queues.
|
|
- `AppRuntime` uses `std::jthread`, which is progress, but queue ownership,
|
|
running flags, thread affinity, and shutdown contracts are not yet component
|
|
contracts.
|
|
- `PP_PANOPAINTER_APP_SOURCES` still includes `${PP_PLATFORM_WEB_SOURCES}`,
|
|
which should be removed in favor of concrete `pp_platform_web` ownership.
|
|
|
|
## Parallel Assignment Rules
|
|
|
|
Coordinator packets for workers should include only:
|
|
|
|
- task id and one-paragraph goal
|
|
- exact write scope
|
|
- allowed read scope
|
|
- debt ids that matter
|
|
- required validation command
|
|
- specific `rg` or `clangd_nav.py` queries
|
|
- current behavior notes needed to avoid broad rediscovery
|
|
|
|
Safe parallel groups:
|
|
|
|
- One worker on canvas/render execution, one worker on generic UI controls, one
|
|
worker on platform CMake cleanup, and one worker on runtime queue contracts
|
|
can run in parallel if write scopes remain disjoint.
|
|
- Do not run two workers against `src/app_runtime.*`, `src/node.*`,
|
|
`src/legacy_canvas_document_io_services.cpp`, or
|
|
`src/legacy_node_stroke_preview_runtime_services.cpp` at the same time.
|
|
- Do not assign both a CMake source-list move and code edits touching the same
|
|
source files to separate workers unless the coordinator serializes the CMake
|
|
integration.
|
|
|
|
## P0 Queue
|
|
|
|
### ARC-RUN-010 - Harden `AppRuntime` Into An Explicit Runtime Service
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
Render/UI/background queues are central to memory and thread safety. The
|
|
current `AppRuntime` owns several `std::jthread` workers, but runtime state is
|
|
still mutable, partly unsynchronized, and app-specific. The working app still
|
|
uses `App::I` as the practical access path to render/UI queues.
|
|
|
|
Write scope:
|
|
|
|
- `src/app_runtime.h`
|
|
- `src/app_runtime.cpp`
|
|
- `src/app.h`
|
|
- `src/legacy_app_runtime_shell_services.cpp`
|
|
- `src/app_core/app_thread.h`
|
|
- `tests/app_core/app_thread_tests.cpp`
|
|
|
|
Read scope:
|
|
|
|
- `src/texture.cpp`
|
|
- `src/rtt.cpp`
|
|
- `src/shape.cpp`
|
|
- `src/shader.cpp`
|
|
- `src/platform_windows/windows_platform_services.cpp`
|
|
|
|
Required work:
|
|
|
|
- Make render/UI/prepared-file/canvas worker running state synchronized or
|
|
atomic, with a single shutdown path per worker.
|
|
- Add explicit runtime service methods for thread-affinity checks and
|
|
post/drain/shutdown semantics.
|
|
- Keep exceptions from escaping worker bodies.
|
|
- Stop exposing queue usage only through `App::I` wrappers for touched call
|
|
sites.
|
|
- Keep behavior identical for same-thread immediate execution and blocking
|
|
render/UI calls.
|
|
|
|
Done when:
|
|
|
|
- Touched queue state has no unsynchronized read/write ambiguity.
|
|
- Worker shutdown drains or rejects queued work according to documented
|
|
behavior.
|
|
- Touched app code can call an explicit runtime service instead of reaching
|
|
queues through singleton state.
|
|
- App-thread planner tests cover shutdown, stopped-worker enqueue, same-thread
|
|
execution, and queue-drain behavior that the live runtime implements.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pp_app_core_app_thread_tests -TestRegex "pp_app_core_app_thread"
|
|
python scripts/dev/check_component_boundaries.py
|
|
```
|
|
|
|
Mini-model packet:
|
|
Start by auditing `render_running_`, `ui_running_`,
|
|
`prepared_file_running_`, `canvas_async_running_`, thread ids, and worker stop
|
|
methods. Do not rewrite GL resources in this task; expose the runtime contract
|
|
needed for the next task.
|
|
|
|
### ARC-RND-010 - Move GL Resource Queueing Behind Renderer Runtime Contracts
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
`RTT`, `Texture2D`, `Shape`, `Shader`, `Font`, and `CanvasLayer` still use
|
|
`App::I->render_task*` directly. That blocks renderer backends and hides thread
|
|
affinity behind a global app singleton.
|
|
|
|
Write scope:
|
|
|
|
- `src/texture.cpp`
|
|
- `src/texture.h`
|
|
- `src/rtt.cpp`
|
|
- `src/rtt.h`
|
|
- `src/shape.cpp`
|
|
- `src/shape.h`
|
|
- `src/shader.cpp`
|
|
- `src/shader.h`
|
|
- `src/font.cpp`
|
|
- `src/font.h`
|
|
- `src/canvas_layer.cpp`
|
|
- `src/canvas_layer.h`
|
|
- narrow adapter files if introduced under `src/renderer_gl/`
|
|
|
|
Read scope:
|
|
|
|
- `src/app_runtime.*`
|
|
- `src/renderer_api/*`
|
|
- `src/renderer_gl/*`
|
|
- `src/paint_renderer/*`
|
|
|
|
Required work:
|
|
|
|
- Introduce a narrow render-dispatch interface or adapter consumed by retained
|
|
GL resource classes.
|
|
- Convert one coherent GL resource family per slice; do not edit every file in
|
|
one worker pass unless the abstraction is already integrated.
|
|
- Preserve blocking versus async semantics exactly.
|
|
- Do not move app policy into `pp_renderer_gl`.
|
|
- Do not add future backend implementation work.
|
|
|
|
Done when:
|
|
|
|
- The touched GL resource family no longer calls `App::I` directly for queueing
|
|
or thread checks.
|
|
- Render-thread assertions use an explicit runtime/render-dispatch contract.
|
|
- CMake ownership remains consistent and no pure renderer API target depends on
|
|
app headers.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pp_renderer_api_tests,pp_renderer_gl_capabilities_tests -TestRegex "pp_renderer|pp_paint_renderer"
|
|
python scripts/dev/check_renderer_api_contract.py
|
|
```
|
|
|
|
Mini-model packet:
|
|
Start with either `Texture2D`/`RTT` or `Shape`/`Shader`, not both. Use `rg -n
|
|
"App::I->render_task|is_render_thread" src/texture.* src/rtt.*` for the first
|
|
slice.
|
|
|
|
### ARC-RND-011 - Split Canvas Document I/O From Render Execution
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
`src/legacy_canvas_document_io_services.cpp` is still the largest working-app
|
|
document/export hotspot and has the highest `App::I` concentration found in the
|
|
review. It mixes license checks, worker dispatch, render readback, progress UI,
|
|
platform publish/flush, and retained `Canvas` mutation.
|
|
|
|
Write scope:
|
|
|
|
- `src/legacy_canvas_document_io_services.cpp`
|
|
- `src/legacy_canvas_document_io_services.h`
|
|
- `src/legacy_document_export_services.*`
|
|
- `src/app_core/document_export.h`
|
|
- `src/paint_renderer/*`
|
|
- focused tests under `tests/app_core` or `tests/paint_renderer`
|
|
|
|
Read scope:
|
|
|
|
- `src/canvas.*`
|
|
- `src/canvas_layer.*`
|
|
- `src/legacy_canvas_render_shell_services.*`
|
|
- `src/platform_api/platform_services.h`
|
|
|
|
Required work:
|
|
|
|
- Pick one export/import family first: equirectangular export, cube-face export,
|
|
layer/frame collection export, or project save/open async I/O.
|
|
- Move orchestration into an app-core or paint-renderer service request that
|
|
accepts explicit document/render/platform dependencies.
|
|
- Leave retained `Canvas` as a final adapter only for data that has not moved.
|
|
- Remove direct `App::I` calls from the touched path.
|
|
- Preserve progress and platform publish behavior.
|
|
|
|
Done when:
|
|
|
|
- One live document/export path is executable through an explicit service
|
|
request rather than by walking `App::I`/`Canvas::I` from the bridge.
|
|
- The retained bridge is visibly thinner and has fewer reasons to know about
|
|
UI, worker, platform, and renderer details at the same time.
|
|
- The touched path has focused validation that exercises the new request
|
|
contract and the retained adapter.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pano_cli,pp_app_core_document_export_tests,pp_paint_renderer_compositor_tests -TestRegex "document_export|paint_renderer"
|
|
```
|
|
|
|
Mini-model packet:
|
|
Do not broaden into all export types. Start with the path that already has the
|
|
strongest pure planning/readiness coverage, then remove only the corresponding
|
|
direct app/canvas singleton reach.
|
|
|
|
### ARC-RND-012 - Make Stroke Preview A Renderer-Owned Service
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
`NodeStrokePreview` has been thinned, but
|
|
`src/legacy_node_stroke_preview_runtime_services.cpp` still owns static worker
|
|
state, render-context handoff, preview texture lifetime, and direct app/canvas
|
|
access. This is a high-risk UI/render/thread boundary.
|
|
|
|
Write scope:
|
|
|
|
- `src/node_stroke_preview.*`
|
|
- `src/legacy_node_stroke_preview_runtime_services.*`
|
|
- `src/legacy_node_stroke_preview_draw_services.*`
|
|
- `src/legacy_node_stroke_preview_sample_services.*`
|
|
- `src/paint_renderer/*`
|
|
- `tests/paint_renderer/*`
|
|
|
|
Read scope:
|
|
|
|
- `src/app_runtime.*`
|
|
- `src/texture.*`
|
|
- `src/rtt.*`
|
|
- `src/canvas.*`
|
|
- `src/node_panel_stroke.*`
|
|
|
|
Required work:
|
|
|
|
- Move one preview execution phase behind a renderer-facing service contract.
|
|
- Replace static worker/resource state for the touched phase with owned service
|
|
state or explicit runtime dependency.
|
|
- Remove direct `App::I`/`Canvas::I` from the touched phase.
|
|
- Preserve preview output and cancellation/shutdown behavior.
|
|
|
|
Done when:
|
|
|
|
- The touched preview phase can be reasoned about without reading the full node
|
|
implementation.
|
|
- Preview worker lifetime is owned and cancellable for the touched phase.
|
|
- Renderer-facing tests cover the contract without linking app texture objects.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pp_paint_renderer_compositor_tests -TestRegex "paint_renderer|stroke_preview"
|
|
```
|
|
|
|
Mini-model packet:
|
|
Start with result copy, live pass request assembly, or worker lifecycle. Do not
|
|
combine all preview phases in one slice.
|
|
|
|
### ARC-UI-010 - Move Generic Controls Out Of `pp_legacy_ui_core`
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
Generic controls still live in `PP_LEGACY_UI_CORE_SOURCES`, keeping
|
|
`pp_panopainter_ui` tied to retained app/UI targets. This is working-app UI
|
|
architecture, not cosmetic cleanup.
|
|
|
|
Write scope:
|
|
|
|
- `src/node_button.*`
|
|
- `src/node_checkbox.*`
|
|
- `src/node_icon.*`
|
|
- `src/node_image.*`
|
|
- `src/node_scroll.*`
|
|
- `src/node_slider.*`
|
|
- `src/node_text.*`
|
|
- `src/node_text_input.*`
|
|
- `src/ui_core/*`
|
|
- `cmake/PanoPainterSources.cmake`
|
|
- `CMakeLists.txt`
|
|
|
|
Read scope:
|
|
|
|
- `src/node.*`
|
|
- `src/layout.*`
|
|
- app-specific `src/node_panel_*`
|
|
- app-specific `src/node_dialog_*`
|
|
|
|
Required work:
|
|
|
|
- Move one generic control family at a time to `pp_ui_core`.
|
|
- Split renderer-neutral state/event/layout logic from retained GL drawing
|
|
when a control still depends on GL classes.
|
|
- Keep app-specific panels and dialogs out of `pp_ui_core`.
|
|
- Update CMake ownership so the source-list change is real.
|
|
|
|
Done when:
|
|
|
|
- At least one generic control family is owned by `pp_ui_core` or has its
|
|
renderer-neutral core owned there with only a narrow retained draw adapter.
|
|
- `PP_LEGACY_UI_CORE_SOURCES` shrinks.
|
|
- Existing UI behavior is unchanged.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pp_ui_core_layout_xml_tests,pp_ui_core_node_lifetime_tests,pp_ui_core_overlay_lifetime_tests -TestRegex "pp_ui_core"
|
|
python scripts/dev/check_component_boundaries.py
|
|
```
|
|
|
|
Mini-model packet:
|
|
Start with the least app-specific control: checkbox, button, icon, image,
|
|
scroll, slider, text, or text input. Do not touch panels/dialogs in the same
|
|
slice.
|
|
|
|
### ARC-UI-011 - Convert UI Ownership To Checked Handles By Default
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
`pp_ui_core` has checked lifetime helpers, but base `Node` and app panels still
|
|
mix raw parent/manager pointers, shared child vectors, raw callback parameters,
|
|
and destroy-during-callback assumptions.
|
|
|
|
Write scope:
|
|
|
|
- `src/node.*`
|
|
- `src/layout.*`
|
|
- `src/legacy_ui_overlay_services.*`
|
|
- one dialog or panel family per slice under `src/node_dialog_*` or
|
|
`src/node_panel_*`
|
|
- `src/ui_core/node_lifetime.*`
|
|
- `src/ui_core/overlay_lifetime.*`
|
|
|
|
Read scope:
|
|
|
|
- call sites found with `rg -n "add_child|remove_child|destroy\\(|on_.*=|Node\\*" src/node_dialog_* src/node_panel_* src/legacy_ui_* src/node.*`
|
|
|
|
Required work:
|
|
|
|
- Convert one popup/dialog/panel family to checked handles or scoped
|
|
connections.
|
|
- Remove raw lifetime assumptions from callbacks in the touched family.
|
|
- Document any remaining raw `Node*` as non-owning views with owner proof.
|
|
- Keep visual behavior and event ordering unchanged.
|
|
|
|
Done when:
|
|
|
|
- The touched UI family can close during callback dispatch without relying on
|
|
dangling raw pointers.
|
|
- Overlay/popup lifetime flows through `pp_ui_core` lifetime primitives by
|
|
default.
|
|
- New touched callbacks are scoped or handle-checked.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pp_ui_core_node_lifetime_tests,pp_ui_core_overlay_lifetime_tests -TestRegex "ui_core_(node_lifetime|overlay_lifetime)"
|
|
```
|
|
|
|
Mini-model packet:
|
|
Pick one family only, such as open/browse dialogs, picker dialog, popup menu,
|
|
layer panel, or stroke panel. Avoid broad `Node` redesign unless the family
|
|
requires a small base helper.
|
|
|
|
### ARC-APP-010 - Reduce App Shells To Composition And Adapters
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
`PP_PANOPAINTER_APP_SOURCES` is still about 9620 lines. The app shell owns
|
|
workflow, dialogs, layout binding, runtime, VR, cloud, brush package, platform
|
|
hooks, and retained document/export adapters.
|
|
|
|
Write scope:
|
|
|
|
- one `src/app_*.cpp` family per slice
|
|
- matching `src/legacy_app_*` service files
|
|
- matching app-core planner/service headers only when needed
|
|
- `cmake/PanoPainterSources.cmake` if ownership moves
|
|
|
|
Read scope:
|
|
|
|
- `src/app.h`
|
|
- relevant app-core headers under `src/app_core`
|
|
- relevant UI node files for the touched workflow
|
|
|
|
Required work:
|
|
|
|
- Pick one shell family: layout menus, dialogs, startup/frame, cloud, brush
|
|
package, recording, VR, or document session.
|
|
- Move retained implementation into a named service with explicit dependencies.
|
|
- Make the app method a thin adapter or composition call.
|
|
- Do not add planner-only coverage unless the app method actually shrinks.
|
|
|
|
Done when:
|
|
|
|
- One app shell file loses real workflow/runtime ownership.
|
|
- The new service accepts explicit `App&`, runtime, platform, UI, document, or
|
|
renderer dependencies instead of reading global state internally.
|
|
- The touched path has focused validation or an app build gate.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pano_cli -TestRegex "pp_app_core|pano_cli_plan"
|
|
```
|
|
|
|
Mini-model packet:
|
|
Start with a single app shell family. Do not mix dialogs, layout, cloud, and VR
|
|
in one worker assignment.
|
|
|
|
### ARC-PLT-010 - Finish Platform Source Ownership In CMake
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
Platform implementation ownership improved, but CMake still leaks Web platform
|
|
sources into `PP_PANOPAINTER_APP_SOURCES`. Platform implementation files should
|
|
belong to concrete `pp_platform_*` targets, not the app source group.
|
|
|
|
Write scope:
|
|
|
|
- `cmake/PanoPainterSources.cmake`
|
|
- `CMakeLists.txt`
|
|
- `src/platform_web/*` only if build integration requires a narrow include or
|
|
factory adjustment
|
|
|
|
Read scope:
|
|
|
|
- `webgl/CMakeLists.txt`
|
|
- `src/platform_android/*`
|
|
- `src/platform_linux/*`
|
|
- `src/platform_apple/*`
|
|
- `src/platform_api/platform_services.h`
|
|
|
|
Required work:
|
|
|
|
- Remove `${PP_PLATFORM_WEB_SOURCES}` from `PP_PANOPAINTER_APP_SOURCES`.
|
|
- Ensure root app/platform targets link `pp_platform_web` only when needed.
|
|
- Keep WebGL retained package entrypoint behavior unchanged.
|
|
- Do not reintroduce `platform_legacy`.
|
|
|
|
Done when:
|
|
|
|
- Concrete Web platform files are not compiled as app sources in the root app
|
|
source group.
|
|
- The source ownership direction is visible in CMake.
|
|
- Platform API boundary checks still pass.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pp_platform_api_tests -TestRegex "pp_platform_api"
|
|
python scripts/dev/check_component_boundaries.py
|
|
```
|
|
|
|
Mini-model packet:
|
|
Keep this structural. Do not edit platform behavior unless CMake exposes a real
|
|
link or include problem.
|
|
|
|
## P1 Queue
|
|
|
|
### ARC-SAFE-010 - Remove Manual Allocation From Touched Ownership Paths
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
The review found manual `new`/`delete` pockets in node loading, canvas, layer
|
|
actions, Wacom/bootstrap helpers, and retained resource cleanup. Some are
|
|
non-owning or placement-new cases, but touched working-app ownership paths
|
|
should move to RAII containers and factories.
|
|
|
|
Write scope:
|
|
|
|
- one selected ownership path at a time, such as `src/legacy_ui_node_loader.*`,
|
|
`src/node.*`, `src/canvas.cpp`, `src/platform_windows/windows_bootstrap_helpers.cpp`,
|
|
or `src/wacom.cpp`
|
|
|
|
Read scope:
|
|
|
|
- immediate owner/caller files for the selected path
|
|
|
|
Required work:
|
|
|
|
- Replace owning raw allocation with `std::unique_ptr`, `std::shared_ptr`,
|
|
`std::vector`, `std::string`, or an explicit RAII wrapper.
|
|
- Preserve non-owning views only where ownership is proven.
|
|
- Avoid mixing this with UI or renderer redesign.
|
|
|
|
Done when:
|
|
|
|
- The touched path has no owning raw `new`/`delete`.
|
|
- Failure paths cannot leak.
|
|
- Lifetime remains clear at call sites.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter -TestRegex "pp_ui_core|pp_app_core"
|
|
```
|
|
|
|
Mini-model packet:
|
|
Start with a single obvious allocation family. `legacy_ui_node_loader` is a
|
|
good first target because it is UI ownership, not rendering behavior.
|
|
|
|
### ARC-SAFE-011 - Replace Remaining Ad Hoc Workers With Runtime-Owned Services
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
Most recent worker conversions use `std::jthread`, but retained worker pockets
|
|
still sit in UI/dialog/cloud/grid/preview services and `std::async` remains in
|
|
`Asset`. The end state requires service-owned cancellation and shutdown.
|
|
|
|
Write scope:
|
|
|
|
- one worker family per slice:
|
|
`src/node_dialog_cloud.*`, `src/legacy_cloud_services.*`,
|
|
`src/legacy_grid_ui_services.*`, `src/asset.*`, or
|
|
`src/legacy_node_stroke_preview_runtime_services.*`
|
|
|
|
Read scope:
|
|
|
|
- `src/app_runtime.*`
|
|
- corresponding app-core/cloud/grid/preview planner headers
|
|
- immediate UI caller files
|
|
|
|
Required work:
|
|
|
|
- Move worker ownership behind a runtime/service contract.
|
|
- Add cancellation or shutdown semantics for the touched worker.
|
|
- Avoid capturing raw nodes across worker completion without checked handles.
|
|
- Preserve progress and completion callbacks.
|
|
|
|
Done when:
|
|
|
|
- The touched worker cannot outlive its owner.
|
|
- Shutdown behavior is explicit and validated.
|
|
- UI completion handoff is handle-safe or owner-checked.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter -TestRegex "pp_app_core|pp_ui_core"
|
|
```
|
|
|
|
Mini-model packet:
|
|
Pick one worker family. Do not perform broad thread cleanup across unrelated
|
|
subsystems in one task.
|
|
|
|
### ARC-WKF-010 - Thin Document Session/Open/Save Bridges
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
The pure document/session planners are extensive, but live bridges still own
|
|
retained prompts, metadata mutation, title updates, history clearing, snapshot
|
|
handoff, and legacy `Canvas` execution.
|
|
|
|
Write scope:
|
|
|
|
- `src/legacy_document_open_services.*`
|
|
- `src/legacy_document_session_services.*`
|
|
- `src/legacy_history_services.*`
|
|
- focused app-core document/session headers only when needed
|
|
|
|
Read scope:
|
|
|
|
- `src/app_core/document_route.h`
|
|
- `src/app_core/document_session.h`
|
|
- `src/app_core/document_canvas.h`
|
|
- `src/app.h`
|
|
- `src/canvas.*`
|
|
|
|
Required work:
|
|
|
|
- Pick one bridge path: open-project confirmation, save-before-workflow,
|
|
save-version, new-document overwrite, history clear, or title update.
|
|
- Move decisions/mutations behind explicit service requests.
|
|
- Keep retained prompts as adapters only.
|
|
|
|
Done when:
|
|
|
|
- One document workflow path has a single obvious owner for decision,
|
|
execution, and metadata mutation.
|
|
- The retained bridge has less direct `App::I`/`Canvas::I` reach.
|
|
- Behavior is covered by existing or focused document-session validation.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pano_cli,pp_app_core_document_session_tests,pp_app_core_document_route_tests -TestRegex "document_(session|route)"
|
|
```
|
|
|
|
Mini-model packet:
|
|
Do not rewrite all document flows. Pick the narrowest path that removes live
|
|
bridge ownership.
|
|
|
|
### ARC-WKF-011 - Split Cloud And Brush Package Work Out Of UI Nodes
|
|
|
|
Status: Ready
|
|
|
|
Why now:
|
|
Cloud browse/download/upload and brush package import/export still mix UI node
|
|
lifetime, worker ownership, storage, network/asset behavior, and app singleton
|
|
reach.
|
|
|
|
Write scope:
|
|
|
|
- one family per slice:
|
|
`src/legacy_cloud_services.*`, `src/node_dialog_cloud.*`,
|
|
`src/legacy_brush_package_import_services.*`,
|
|
`src/legacy_brush_package_export_services.*`,
|
|
`src/legacy_brush_preset_services.*`,
|
|
`src/node_panel_brush.cpp`
|
|
|
|
Read scope:
|
|
|
|
- `src/app_core/document_cloud.h`
|
|
- `src/app_core/brush_package_import.h`
|
|
- `src/app_core/brush_package_export.h`
|
|
- `src/assets/brush_package.*`
|
|
- relevant panel/dialog headers
|
|
|
|
Required work:
|
|
|
|
- Separate worker/network/asset execution from node lifetime.
|
|
- Use app-core requests and asset helpers where they already exist.
|
|
- Use checked handles for UI completion callbacks.
|
|
- Preserve current cloud and brush package UX.
|
|
|
|
Done when:
|
|
|
|
- One cloud or brush package path can be understood without reading panel or
|
|
dialog internals first.
|
|
- The touched UI node is a view/controller shell, not the workflow owner.
|
|
- The touched worker cannot outlive its service/UI owner.
|
|
|
|
Validation:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File scripts\automation\quiet-validate.ps1 -BuildTargets PanoPainter,pano_cli,pp_app_core_document_cloud_tests,pp_app_core_brush_package_import_tests,pp_app_core_brush_package_export_tests,pp_assets_brush_package_tests -TestRegex "document_cloud|brush_package"
|
|
```
|
|
|
|
Mini-model packet:
|
|
Cloud and brush package work are separate packets. Do not assign both to one
|
|
small worker.
|
|
|
|
## Deferred On Purpose
|
|
|
|
- Vulkan, Metal, WebGPU, and broad future-backend implementation.
|
|
- OpenXR implementation beyond boundary cleanup needed to remove OpenVR debt.
|
|
- Package-only migration that does not affect root app architecture.
|
|
- CLI/planner-only expansion.
|
|
- Broad warning cleanup without ownership movement.
|
|
- Documentation-only progress claims.
|