Files
panopainter/docs/modernization/debt.md

34 KiB

Modernization Debt Log

Status: live Last updated: 2026-06-03

Every shortcut, temporary adapter, retained vendored dependency, skipped platform gate, compatibility shim, or incomplete automation path must be recorded here before it lands. Entries must be specific enough for a future agent or engineer to remove them without reconstructing context from chat.

Entry Rules

  • Add an entry before merging the shortcut.
  • Reference the debt id in code comments, TODOs, ADRs, or roadmap notes.
  • Include an owner, reason, validation command, and removal condition.
  • Do not close an entry until the removal condition is met and validated.
  • Prefer deleting shortcuts over expanding this log.

Open Debt

ID Status Owner Item Reason Validation Removal Condition
DEBT-0001 Open Modernization Existing platform build files remain alongside new CMake Required for incremental migration without losing platform coverage Existing platform builds plus new CMake configure Remove after all platform builds consume shared CMake targets
DEBT-0002 Open Modernization Vendored SDK and patched libraries retained initially Some dependencies are SDK-only, patched, or have platform-specific binaries Dependency inventory and platform build smoke tests Replace with vcpkg packages or document permanent vendored status after triplet evaluation
DEBT-0003 Open Modernization Existing singletons remain during initial split; App::open_document, App::request_close, App::share_file, App::cloud_upload, App::cloud_upload_all, App::cloud_browse, App::rec_start, App::rec_stop, App::rec_clear, App::rec_export, file-menu save actions, NodeCanvas save hotkeys, new/open/browse dirty-document workflow prompts, new-document target/resolution/overwrite decisions, save-as document file naming and overwrite decisions, save-version target decisions, export start/menu/target naming/path decisions, share-file saved-path decisions, file/image/save/directory picker selected-path decisions, display-file external-open decisions, virtual-keyboard visibility decisions, recording lifecycle/export progress decisions, cloud-upload prompt/save-before-upload decisions, cloud-browse availability and selected-download decisions, bulk cloud-upload progress decisions, tools/options app preference decisions, app status/display decisions, document resize decisions, layer rename/menu decisions, Tools menu/panel decisions, About menu/diagnostic decisions, main toolbar/status decisions, pano_cli classify-open, pano_cli plan-open-route, pano_cli plan-file-menu, pano_cli plan-new-document, pano_cli plan-document-file, pano_cli plan-document-version, pano_cli plan-export-start, pano_cli plan-export-menu, pano_cli plan-export-target, pano_cli plan-recording-session, pano_cli plan-app-preferences, pano_cli plan-app-status, pano_cli plan-tools-menu, pano_cli plan-tools-panel, pano_cli plan-about-menu, pano_cli plan-main-toolbar, pano_cli plan-document-resize, pano_cli plan-layer-rename, pano_cli plan-layer-menu, pano_cli plan-share-file, pano_cli plan-picked-path, pano_cli plan-display-file, pano_cli plan-keyboard-visibility, pano_cli plan-cloud-upload, pano_cli plan-cloud-browse, pano_cli plan-cloud-upload-all, and pano_cli simulate-app-session now consume pure pp_app_core route/session/export/recording/preferences/status/share/platform-I/O/display/keyboard/cloud/resize/layer/tools/about/toolbar contracts, but document creation/loading, brush import execution, saving, export execution, tools/options UI execution, Tools panel creation/execution, About dialog/diagnostic execution, toolbar/status dialog/history/canvas execution, status/display UI rendering, document resize execution, layer rename/menu execution, settings persistence, platform share service execution, picker service execution, display-file service execution, keyboard service execution, recording/MP4 execution, cloud upload execution, and cloud browse/download execution still reach legacy Canvas::I/UI/network/video/platform singletons Avoid behavior changes while introducing component boundaries App launch and component tests; pp_app_core_document_route_tests; pp_app_core_file_menu_tests; pp_app_core_document_export_tests; pp_app_core_document_recording_tests; pp_app_core_app_preferences_tests; pp_app_core_app_status_tests; pp_app_core_tools_menu_tests; pp_app_core_about_menu_tests; pp_app_core_main_toolbar_tests; pp_app_core_document_resize_tests; pp_app_core_document_layer_tests; pp_app_core_document_sharing_tests; pp_app_core_document_platform_io_tests; pp_app_core_document_cloud_tests; pp_app_core_document_session_tests; pano_cli classify-open --path D:/Paint/demo.ppi; pano_cli plan-open-route --path D:/Paint/demo.ppi --unsaved; pano_cli plan-file-menu --command save-as; pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3 --target-exists; pano_cli plan-document-file --work-dir D:/Paint --name demo --target-exists; pano_cli plan-document-version --directory D:/Paint --doc-name demo.01 --existing-path D:/Paint/demo.02.ppi; pano_cli plan-export-start --requires-license --demo; pano_cli plan-export-menu --kind animation-mp4 --demo; pano_cli plan-export-target --kind file --work-dir D:/Paint --doc-name demo --extension .png; pano_cli plan-recording-session --running --frame-count 12; pano_cli plan-app-preferences --ui-scale 1.5 --display-density 2 --current-scale 1.6 --scale-option 1 --scale-option 1.5 --rtl; pano_cli plan-app-status --doc-name demo --unsaved --resolution 2048 --resolution-index 3 --zoom 1.25 --history-bytes 1572864 --recording-running --encoder-available --encoded-frames 12; pano_cli plan-tools-menu --command shortcuts; pano_cli plan-tools-panel --panel layers; pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7; pano_cli plan-main-toolbar --command undo --undo-count 2; pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4; pano_cli plan-layer-rename --old-name Base --new-name Paint; pano_cli plan-layer-menu --command merge --current-index 2 --lower-name Paint; pano_cli plan-share-file --path D:/Paint/demo.ppi; pano_cli plan-picked-path --path D:/Paint/demo.ppi; pano_cli plan-display-file --path D:/Paint/export.png; pano_cli plan-keyboard-visibility --visible; pano_cli plan-cloud-upload --new-document --unsaved; pano_cli plan-cloud-browse --selected-file demo.ppi; pano_cli plan-cloud-upload-all --file-count 3; pano_cli simulate-app-session --unsaved --save-intent save-dirty-version; pano_cli simulate-app-session --no-canvas; ctest --preset desktop-fast --build-config Debug Replace singleton reaches with context/service injection at component boundaries
DEBT-0004 Open Modernization Android, Linux, WebGL, Apple, and AppX build files remain platform-specific until root CMake alignment reaches them Prevent platform regressions during incremental migration; raw Windows .sln/.vcxproj files were removed on 2026-05-31 by user decision cmake --preset windows-msvc-default; platform-specific configure/build smoke checks as each platform is migrated Root CMake owns every platform source list and package path
DEBT-0005 Open Modernization Temporary local CTest harness is used before Catch2 is wired through vcpkg vcpkg is not currently on PATH, but headless tests need to run now ctest --preset desktop-fast --build-config Debug Replace tests/test_harness.h tests with Catch2 tests once vcpkg toolchain/presets are validated
DEBT-0007 Open Modernization vcpkg.json and windows-msvc-vcpkg-headless are validated for the headless Windows component matrix, 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 $env:VCPKG_ROOT="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\vcpkg"; cmake --preset windows-msvc-vcpkg-headless; ctest --preset desktop-fast-vcpkg --build-config Debug 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 preset is used for local validation because the VS 2026 generator is not installed here The target VS 2026 preset must remain, but this machine configures with Visual Studio 17 2022 cmake --preset windows-msvc-default; ctest --preset desktop-fast --build-config Debug Validate windows-vs2026-x64 on a machine with Visual Studio 2026 installed and make it the default Windows validation preset
DEBT-0009 Open Modernization Android root CMake validation currently builds headless targets only, not APK/package variants; standard arm64/x64, Quest arm64, and Focus/Wave arm64 have named root build presets and share the refreshed platform-build component matrix 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 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, and stroke-script-to-face-payload CLI automation, but it is not yet wired to legacy Canvas, legacy save, or legacy action commands 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; pp_document_tests; pp_document_ppi_import_tests; pp_document_ppi_export_tests; pano_cli_simulate_document_edits_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 Legacy document behavior is represented by pp_document tests and the app consumes it through a boundary/facade
DEBT-0011 Open Modernization package-smoke validates the Windows CMake app artifact and now reports a structured package readiness matrix for Windows AppX, Android standard/Quest/Focus APKs, Apple bundles, and WebGL output, but those 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; bash -n scripts/automation/package-smoke.sh Package-smoke builds and validates Windows AppX, Android APK variants, 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
DEBT-0014 Open Modernization windows-clangcl-asan now configures as a headless Ninja/clang-cl preset and uses the release MSVC runtime required by ASan, but local builds still fail because installed clang-cl 18.1.8 is paired with VS 2026-preview STL headers that require Clang 20 or newer Sanitizer validation should be local and repeatable, but this machine's compiler/header pairing is incompatible cmake --fresh --preset windows-clangcl-asan; cmake --build --preset windows-clangcl-asan --target pp_foundation Install/use Clang 20+ with the VS 2026 STL, or point the preset at a compatible VS 2022 toolchain, then make platform-build.ps1 -Presets windows-clangcl-asan pass for the headless matrix
DEBT-0015 Open Modernization Cursor visibility requests now consume pure pp_app_core planning through pano_cli plan-cursor-visibility, App::show_cursor/App::hide_cursor dispatch through PlatformServices without platform guards, and Windows live execution uses injected WindowsPlatformServices, but macOS cursor execution still reaches the retained fallback adapter Keep canvas cursor behavior stable while platform shells are extracted incrementally pp_app_core_document_platform_io_tests; pano_cli plan-cursor-visibility --visible; ctest --preset desktop-fast --build-config Debug Cursor visibility execution is owned by injected pp_platform_* services for every supported platform
DEBT-0016 Open Modernization Clipboard get/set requests now consume pure pp_app_core planning through pano_cli plan-clipboard-read and pano_cli plan-clipboard-write, and Windows live execution uses injected WindowsPlatformServices, but Apple/Android clipboard execution still reaches retained fallback adapter branches from App::clipboard_get_text and App::clipboard_set_text Keep picker/color text clipboard behavior stable while platform shells are extracted incrementally pp_app_core_document_platform_io_tests; pano_cli plan-clipboard-write --text #ff00aa; ctest --preset desktop-fast --build-config Debug Clipboard execution is owned by injected pp_platform_* services for every supported platform
DEBT-0017 Open Modernization Startup storage path preparation, App::clipboard_get_text, App::clipboard_set_text, App::show_cursor, App::hide_cursor, App::showKeyboard, App::hideKeyboard, App::display_file, App::share_file, native app/window close, UI-thread lifecycle hooks, render-context acquire/release/present hooks, render-target binding hooks, render platform hint hooks, render debug callback hooks, render-capture frame hooks, recording cleanup, live asset/layout reload policy, diagnostic stacktrace/crash hooks, per-frame platform hooks, App::pick_image, App::pick_file, the non-writer App::pick_file_save, App::pick_dir, and prepared-file save/download handoff now call the SDK-free pp::platform::PlatformServices interface, and Windows injects WindowsPlatformServices from src/platform_windows/windows_platform_services.*; non-Windows live implementations still use src/platform_legacy/legacy_platform_services.*, a named fallback adapter that forwards to retained Apple/Android/Linux/Web bridge functions and retained no-op branches Preserve behavior while moving platform execution behind a testable service boundary before platform shell implementations are injected pp_platform_api_tests; pp_app_core_document_platform_io_tests; ctest --preset desktop-fast --build-config Debug; powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug Replace src/platform_legacy/legacy_platform_services.* with injected pp_platform_* service implementations owned by each non-Windows platform shell
DEBT-0019 Open Modernization Unreferenced-parameter warnings are muted globally through pp_project_warnings with MSVC /wd4100 and Clang/GCC -Wno-unused-parameter Legacy callbacks, virtual hooks, serializer methods, and platform/API compatibility functions carry many intentionally unused parameters during the component split; muting this keeps stricter warning builds focused on higher-signal migration issues cmake --build --preset windows-msvc-default --config Debug --target PanoPainter; ctest --preset desktop-fast --build-config Debug; cmake --build --preset linux-clang --target pp_foundation Remove /wd4100 and -Wno-unused-parameter, mark intentionally unused parameters with names/comments or [[maybe_unused]], and make the Windows app plus headless Clang/GCC tests pass without unreferenced-parameter warnings
DEBT-0020 Open Modernization Document resize dialog state, selected-resolution planning, and execution dispatch now consume pure pp_app_core through NodeDialogResize, App::dialog_resize, pano_cli plan-document-resize, and the DocumentResizeServices boundary, but the live adapter still calls legacy Canvas::resize, updates the legacy app title, and clears legacy ActionManager history Preserve existing layer/frame GPU resize behavior while the document model and canvas execution boundary are extracted incrementally pp_app_core_document_resize_tests; pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4; ctest --preset desktop-fast --build-config Debug Document resize execution is owned by injected document/app services with no legacy resize adapter, title shim, or direct ActionManager history clearing
DEBT-0021 Open Modernization Layer rename and layer panel operation planning now consume pure pp_app_core through App::dialog_layer_rename, App::init_sidebar layer callbacks, pano_cli plan-layer-rename, and pano_cli plan-layer-operation, but live execution still mutates legacy Canvas layer state, NodeLayer/NodePanelLayer, and ActionManager undo entries directly Preserve existing UI/canvas behavior while document layer commands and undo history are extracted incrementally pp_app_core_document_layer_tests; pano_cli plan-layer-rename --old-name Base --new-name Paint; pano_cli plan-layer-operation --kind add --layer-count 2 --index 1 --name Paint; ctest --preset desktop-fast --build-config Debug Layer command execution is owned by the document/app command boundary with legacy Canvas/UI nodes acting only as adapters or removed entirely
DEBT-0022 Open Modernization Animation panel frame command planning now consumes pure pp_app_core through NodePanelAnimation and pano_cli plan-animation-operation, and pp_legacy_ui_core temporarily links pp_app_core, but live execution still mutates legacy Canvas/Layer frame state and animation playback state directly Preserve existing animation panel behavior while timeline/frame commands move toward the document/app command boundary pp_app_core_document_animation_tests; pano_cli plan-animation-operation --kind add --frame-count 2 --current-frame 0; pano_cli plan-animation-operation --kind next --total-duration 5 --current-frame 4; ctest --preset desktop-fast --build-config Debug Animation frame/timeline execution is owned by the document/app command boundary with legacy Canvas/Layer/UI nodes acting only as adapters or removed entirely
DEBT-0023 Open Modernization Brush/color/preset/stroke-settings UI planning and execution dispatch now consume pure pp_app_core through App::init_sidebar, restored/docked floating-panel callbacks, pano_cli plan-brush-operation, and the BrushUiServices boundary, but the live adapter still mutates legacy Brush, calls legacy brush texture loading, and refreshes legacy quick/stroke/color widgets Preserve existing brush UI behavior while brush commands move toward a brush/app command boundary and asset-managed texture selection pp_app_core_brush_ui_tests; pano_cli plan-brush-operation --kind color --r 0.25 --g 0.5 --b 0.75 --a 1; pano_cli plan-brush-operation --kind pattern --path data/patterns/noise.png --thumb data/patterns/thumbs/noise.png; ctest --preset desktop-fast --build-config Debug Brush color/texture/preset/stroke-settings execution is owned by injected brush/app/asset/UI services with no legacy brush adapter
DEBT-0024 Open Modernization Grid/heightmap/lightmap UI planning now consumes pure pp_app_core through NodePanelGrid and pano_cli plan-grid-operation, but live execution still performs legacy image loading, OpenGL texture updates, nanort lightmap baking, progress UI, and Canvas::draw_objects commit directly Preserve grid/lightmap behavior while moving renderable grid commands toward app/renderer/document boundaries pp_app_core_grid_ui_tests; pano_cli plan-grid-operation --kind render --float32 --texture-resolution 1024 --samples 32; ctest --preset desktop-fast --build-config Debug Grid heightmap/lightmap execution is owned by app/renderer/document services with NodePanelGrid acting only as UI adapter
DEBT-0025 Open Modernization Quick brush/color slot and mini-state planning and execution dispatch now consume pure pp_app_core through NodePanelQuick, pano_cli plan-quick-operation, and the QuickUiServices boundary, but the live adapter still mutates legacy quick UI widgets, Brush previews, color picker popup state, and preset popup state Preserve quick-panel behavior while quick brush/color commands move toward a brush/app command boundary with safer automation coverage pp_app_core_quick_ui_tests; pano_cli plan-quick-operation --kind brush --current-index 0 --slot-index 2; pano_cli plan-quick-operation --kind restore --brush-index 2 --color-index 1 --fire-event; ctest --preset desktop-fast --build-config Debug Quick-panel selection, popup, restore, reset, brush preview, and color execution are owned by injected app/brush/UI services with no legacy quick-panel adapter
DEBT-0026 Open Modernization Toolbar history command planning and execution dispatch now consume pure pp_app_core through App::init_toolbar_main, NodeCanvas, pano_cli plan-history-operation, and the HistoryUiServices boundary, but the live adapter still mutates legacy ActionManager stacks directly Preserve undo/redo/clear behavior while moving action history toward document/app command services pp_app_core_history_ui_tests; pano_cli plan-history-operation --kind undo --undo-count 2; pano_cli plan-history-operation --kind clear --undo-count 2 --redo-count 1 --memory-bytes 4096; ctest --preset desktop-fast --build-config Debug Undo/redo/clear execution is owned by injected document/app history services with no legacy ActionManager adapter
DEBT-0027 Open Modernization Canvas draw-tool toolbar command, canvas input mode switching, and active-state planning/execution dispatch now consume pure pp_app_core through App::init_toolbar_draw, App::update, NodeCanvas, pano_cli plan-canvas-tool, pano_cli plan-canvas-tool-state, and the CanvasToolServices boundary, but live adapters still mutate or read legacy Canvas mode state, pen picking state, touch-lock state, and transform copy/cut action objects Preserve current toolbar, stylus eraser, and keyboard draw/erase behavior while canvas input/tools move toward an app/document command boundary pp_app_core_canvas_tool_ui_tests; pano_cli plan-canvas-tool --kind copy; pano_cli plan-canvas-tool-state --mode draw --picking --touch-lock; ctest --preset desktop-fast --build-config Debug Canvas tool selection, toolbar state refresh, picking, touch lock, stylus eraser/key mode switching, and transform action execution are owned by injected app/document/canvas services with no legacy toolbar/canvas adapter
DEBT-0028 Open Modernization Canvas clear command planning and execution dispatch now consume pure pp_app_core through App::init_toolbar_main, pano_cli plan-canvas-clear, and the DocumentCanvasClearServices boundary, but the live adapter still calls legacy Canvas::clear, which records ActionLayerClear, clears the current layer/frame, and marks legacy Canvas::I unsaved Preserve clear-current-layer behavior while canvas/document commands move toward document/app command services pp_app_core_document_canvas_tests; pano_cli plan-canvas-clear --r 0 --g 0.1 --b 0.2 --a 0.3; pano_cli plan-canvas-clear --no-canvas; ctest --preset desktop-fast --build-config Debug Canvas clear execution, undo recording, dirty-state updates, and clear color handling are owned by injected document/app services with no legacy canvas-clear adapter
DEBT-0029 Open Modernization Image import route planning and execution dispatch now consume pure pp_app_core through the File menu, pano_cli plan-image-import, and the DocumentImageImportServices boundary, but the live adapter still loads images with legacy Image, calls legacy Canvas::import_equirectangular, or configures legacy import transform mode directly Preserve current File > Import behavior while image import moves toward document/app/asset command services pp_app_core_document_import_tests; pano_cli plan-image-import --width 4096 --height 2048; pano_cli plan-image-import --width 1024 --height 1024; ctest --preset desktop-fast --build-config Debug Image loading, equirectangular import, transform-placement import, and failure reporting are owned by injected document/app/asset services with File-menu callbacks acting only as adapters and no legacy image-import adapter
DEBT-0030 Open Modernization File export menu action planning and execution dispatch now consume pure pp_app_core through the File menu, pano_cli plan-export-menu, and the DocumentExportMenuServices boundary, but the live adapter still opens legacy export dialogs and then reaches legacy canvas/render/video export code Preserve current export menu behavior while export command execution moves toward document/app/renderer/video services pp_app_core_document_export_tests; pano_cli plan-export-menu --kind png; pano_cli plan-export-menu --kind animation-mp4 --demo; pano_cli plan-export-menu --kind layers --no-canvas; ctest --preset desktop-fast --build-config Debug Export menu routing, license gating, target creation, image/layer/cube/depth/animation/timelapse execution, and error reporting are owned by injected document/app/renderer/video services with File-menu callbacks acting only as UI adapters and no legacy export adapter
DEBT-0031 Open Modernization Top-level File menu command planning and execution dispatch now consume pure pp_app_core through App::init_menu_file, pano_cli plan-file-menu, and the FileMenuServices boundary, but the live adapter still invokes legacy dialogs, platform pickers, cloud code, share code, and canvas import/export paths directly Preserve File menu behavior while app workflows move toward app/document/platform command services pp_app_core_file_menu_tests; pano_cli plan-file-menu --command save-as; pano_cli plan-file-menu --command import; pano_cli plan-file-menu --command cloud-upload; ctest --preset desktop-fast --build-config Debug File menu routing, picker dispatch, save/share/cloud/resize/export execution, and image/project import execution are owned by injected app/document/platform services with App::init_menu_file acting only as a UI adapter and no legacy File menu adapter
DEBT-0032 Open Modernization Layer menu command planning and execution dispatch now consume pure pp_app_core through App::init_menu_layer, pano_cli plan-layer-menu, and the DocumentLayerMenuServices boundary, but the live adapter still calls legacy Canvas::clear, App::dialog_layer_rename, NodePanelLayer::merge, and reads Canvas::I animation/layer state directly Preserve existing Layer menu behavior while layer commands move toward document/app services pp_app_core_document_layer_tests; pano_cli plan-layer-menu --command merge --current-index 2 --lower-name Paint; pano_cli plan-layer-menu --command rename --no-current-layer; ctest --preset desktop-fast --build-config Debug Layer clear, rename, merge-down execution, animation gating, and selected-layer state are owned by injected document/app services with Layer-menu callbacks acting only as UI adapters and no legacy Layer menu adapter
DEBT-0033 Open Modernization Tools menu planning and direct command execution dispatch now consume pure pp_app_core through App::init_menu_tools, pano_cli plan-tools-menu, pano_cli plan-tools-panel, and the ToolsMenuServices boundary, but live adapters still construct legacy NodePanelFloating panels, mutate legacy panel nodes, clear CanvasModeGrid, reset NodeCanvas camera state, open legacy shortcuts UI, and call the iOS SonarPen bridge directly Preserve current Tools menu behavior while UI shell actions move toward app/UI/platform services pp_app_core_tools_menu_tests; pano_cli plan-tools-menu --command shortcuts; pano_cli plan-tools-panel --panel layers; pano_cli plan-tools-panel --panel animation --already-visible; ctest --preset desktop-fast --build-config Debug Tools panel creation, submenu routing, grid clear, camera reset, shortcuts dialog, and SonarPen dispatch are owned by injected app/UI/platform services with App::init_menu_tools acting only as a UI adapter and no legacy Tools adapter
DEBT-0034 Open Modernization About menu command planning and execution dispatch now consume pure pp_app_core through App::init_menu_about, pano_cli plan-about-menu, and the AboutMenuServices boundary, but the live adapter still opens legacy About/manual/what's-new dialogs, invokes the injected crash hook, and runs the legacy Canvas stroke performance test directly Preserve About menu behavior while dialogs and diagnostics move toward app/UI/platform services pp_app_core_about_menu_tests; pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7; pano_cli plan-about-menu --command performance --no-canvas; ctest --preset desktop-fast --build-config Debug About/manual/what's-new dialog dispatch, crash-test dispatch, and performance-test execution are owned by injected app/UI/platform services with App::init_menu_about acting only as a UI adapter and no legacy About adapter
DEBT-0035 Open Modernization Main toolbar/status command planning and execution dispatch now consume pure pp_app_core through App::init_toolbar_main, pano_cli plan-main-toolbar, and the MainToolbarServices boundary, and history/canvas commands now hand off through HistoryUiServices and DocumentCanvasClearServices, but the live adapter still opens legacy open/save/settings/message-box dialogs and delegates to legacy history/canvas adapters Preserve reachable toolbar/status behavior while app shell commands move toward app/document/UI services pp_app_core_main_toolbar_tests; pano_cli plan-main-toolbar --command undo --undo-count 2; pano_cli plan-main-toolbar --command clear-canvas --no-canvas; ctest --preset desktop-fast --build-config Debug Open/save/settings/message-box routing, undo/redo/clear-history execution, and canvas-clear execution are owned by injected app/document/UI services with App::init_toolbar_main acting only as a UI adapter and no legacy toolbar adapter

Closed Debt

ID Status Owner Item Reason Validation Removal Condition
DEBT-0006 Closed Modernization pano_cli create-document validates and emits JSON command contracts but does not yet invoke the legacy document/app model The document model had not been extracted from Canvas/App yet ctest --preset desktop-fast --build-config Debug; pano_cli_create_document_smoke Closed on 2026-05-31: command now constructs a real pp_document::CanvasDocument
DEBT-0018 Closed Modernization pp_renderer_gl owned a tested OpenGlInitialState plan for PanoPainter startup depth/blend policy, but App::init still executed the plan through direct OpenGL calls Preserve behavior while moving renderer policy into the backend boundary before a live IRenderDevice/command context owns startup execution pp_renderer_gl_capabilities_tests; ctest --preset desktop-fast --build-config Debug; powershell -ExecutionPolicy Bypass -File scripts\automation\package-smoke.ps1 -Preset windows-msvc-default -Configuration Debug Closed on 2026-06-03: pp_renderer_gl::apply_panopainter_initial_state now applies the startup state through a tested backend dispatch contract consumed by App::init