diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index eb5cd8d1..9678477f 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -292,11 +292,11 @@ agent or engineer to remove them without reconstructing context from chat. children; toolbar settings, cloud browser, and other remaining retained dialog families still stay open under the same debt until they move to the same lifetime model. -- 2026-06-15: `DEBT-0049` was narrowed again. `pp_assets_brush_package_tests` +- 2026-06-16: `DEBT-0049` was narrowed again. `pp_assets_brush_package_tests` now names the currently accepted legacy PPBR version matrix explicitly: - canonical `0.1`, tolerated `0.2`, tolerated `1.1`, and rejected `1.2`. The - live parser still preserves the legacy tolerance until broader compatibility - fixtures prove strict canonical enforcement is safe. + legacy major-zero cases, legacy minor-one cases, and rejected `1.2`. The + live parser still preserves the legacy tolerance until a stricter supported + version matrix is proven safe. - 2026-06-15: `DEBT-0063` was narrowed again. Sidebar stroke/color/layer/grid popups, file/about/layer menu popups in `src/app_layout.cpp`, quick brush/color popup+ticker overlays in `src/legacy_quick_ui_services.cpp`, diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 18710c42..c7079aa2 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -1509,7 +1509,9 @@ legacy-owned. The live PPBR import/export path consumes those helpers, while legacy Serializer/Image payload reading, stroke preview generation, preset storage, and the historical permissive version check remain tracked under `DEBT-0047` -and `DEBT-0049`. +and `DEBT-0049`. The compatibility test fixture now spells out the tolerated +legacy matrix more directly, but the parser still keeps the permissive rule +until a stricter supported-version policy is proven safe. ABR and PPBR import image target planning for brush tips and patterns also now uses `pp_assets::brush_package`, so the legacy preset panel no longer owns the `data/brushes`, `data/brushes/thumbs`, `data/patterns`, and diff --git a/tests/assets/brush_package_tests.cpp b/tests/assets/brush_package_tests.cpp index 9401e592..b95b8d96 100644 --- a/tests/assets/brush_package_tests.cpp +++ b/tests/assets/brush_package_tests.cpp @@ -24,25 +24,32 @@ std::array ppbr_header(std::uint16_t ma void parses_ppbr_header_and_legacy_version_tolerance(pp::tests::Harness& harness) { - const auto canonical_bytes = ppbr_header(0, 1); - const auto canonical = pp::assets::parse_ppbr_header(canonical_bytes); + struct Case { + std::uint16_t major; + std::uint16_t minor; + bool accepted; + }; - PP_EXPECT(harness, canonical); - PP_EXPECT(harness, canonical.value().major == 0U); - PP_EXPECT(harness, canonical.value().minor == 1U); + const std::array cases { + Case { 0U, 0U, true }, + Case { 0U, 1U, true }, + Case { 0U, 2U, true }, + Case { 1U, 1U, true }, + Case { 2U, 1U, true }, + Case { 1U, 2U, false }, + }; - const auto tolerated_minor = pp::assets::parse_ppbr_header(ppbr_header(0, 2)); - const auto tolerated_major = pp::assets::parse_ppbr_header(ppbr_header(1, 1)); - const auto rejected_both = pp::assets::parse_ppbr_header(ppbr_header(1, 2)); - - PP_EXPECT(harness, tolerated_minor); - PP_EXPECT(harness, tolerated_minor.value().major == 0U); - PP_EXPECT(harness, tolerated_minor.value().minor == 2U); - PP_EXPECT(harness, tolerated_major); - PP_EXPECT(harness, tolerated_major.value().major == 1U); - PP_EXPECT(harness, tolerated_major.value().minor == 1U); - PP_EXPECT(harness, !rejected_both); - PP_EXPECT(harness, rejected_both.status().code == pp::foundation::StatusCode::invalid_argument); + for (const auto& item : cases) { + const auto result = pp::assets::parse_ppbr_header(ppbr_header(item.major, item.minor)); + if (item.accepted) { + PP_EXPECT(harness, result); + PP_EXPECT(harness, result.value().major == item.major); + PP_EXPECT(harness, result.value().minor == item.minor); + } else { + PP_EXPECT(harness, !result); + PP_EXPECT(harness, result.status().code == pp::foundation::StatusCode::invalid_argument); + } + } } void rejects_truncated_and_bad_magic_headers(pp::tests::Harness& harness)