Files
qt6-migration-pipeline/QT6_MIGRATION_BRANCHES_SUMMARY.md
T
berrux-dev 4911aa6d80
Qt6 Migration CI / migrate (push) Has been cancelled
Merge Prompt and Report
2026-09-28 08:34:13 +02:00

28 KiB
Raw Blame History

Qt6 Migration Branches Summary Report

Executive Summary

Status: ✅ ALL MIGRATION BRANCHES INTEGRATED AND VALIDATED Target Branch: feature/qt6-migration-projects-app-tools-viewer-validation (593c221d2) Qt Version: 6.10.2 (/opt/Qt/6.10.2/gcc_64) Report Date: 2026-09-28

The Qt5 → Qt6 migration of the Legatus codebase was executed as a branch pipeline: ~14 independent per-module/per-area migration branches (Phase 1) were developed in parallel by Torsten Wierschin / twi-devel and berrux_dev, and were then consolidated through a four-stage integration chain (Phase 2) into the final branch feature/qt6-migration-projects-app-tools-viewer-validation (593c221d2, 257 commits beyond main).

All work was validated with three full Docker build/test runs (new_docker_build.sh, prebuilt image legatus-qt6-prebuilt:latest, cmake 4.2.3):

Run Configuration Build Result ctest Result
1 BUILD_RTI=ON BUILD_GRANTLEE=ON, Groups 1–3 100 % 614 tests: 584 Passed / 30 Not Run / 0 Failed / 0 Timeout
2 + BUILD_ARCGIS=ON BUILD_CODIFICATION=ON, Groups 4–11 + codification, BUILD_WLS=ON Groups 1–4 100 % green; Groups 5–11 built except documented base-state failures 615 tests: 577 Passed / 34 Not Run / 2 Failed / 2 Timeout — exactly the 4 documented base-state failures, no new regressions
3 --build-viewer-only Viewer group 100 % (situationMapCommon, advancedSymbologyXML, LtsDataView, LtsDataViewTest, LtsReportDisplay) 34 tests: LtsDataViewTest PASSED (1.04 s) / 33 Not Run / 0 Failed / 0 Timeout

Bottom line: The merge introduced zero ctest regressions and zero new build failures — every observed failure was proven pre-existing (base-state) via per-file git provenance checks. Remaining failures are classified base-state blockers (see Remaining Work). All commits are GPG-signed (git verify-commit = Good). The result is not pushed (per task instruction).


Migration Scope

  • Source (read-only legacy tree): qt5-before/qt5-legatus-legacy
  • Target (migrated tree): qt6-after/qt6-migrated-legatus (repo qt-migration-legatus, a git submodule of the pipeline repo)
  • Toolchain: Qt 6.10.2, rtiddsgen 7.7.0 (code generation for DDS/RTI types), cmake 4.2.3, KDReports-qt6 2.3.95, ArcGIS Maps SDK for Qt 300.0.0
  • Migrated areas covered by the branch set:
    • Core/Z module (NGL core libraries)
    • DDS core + generated DDS/RTI targets (rtiddsgen 7.7.0 code generation)
    • Lts/Proxies, Lts/Services (incl. residual sources ported to the generated API)
    • Lts/Viewer (SituationMap, Symbology, DataView, ReportDisplay) incl. ArcGIS-dependent targets
    • LTS Tools (Groups 6–9, incl. Group 9 R/S/T/V/W)
    • LTS Projects (GROUP10, 9 project plugins) and LTS Application (GROUP11)
    • Test infrastructure: per-service unit tests, integration tests, ctest integration
  • Out of scope / blockers: ArcGIS TaskWatcher API redesign (SDK 300 removed the class), LtsSession full implementation (currently an empty stub), base-state Qt6 API debt in a handful of tool sources, base-state apps.json IID checker failures.

Branch Inventory

Commit counts are git rev-list --count main..head with main = 99136e946 (2026-08-13, initial commit).

Phase 1 — Independent migration branches

Branch Head Date Author Scope Commits In final branch
origin/feature/migrate-module-z-only 882f783bc 2026-09-17 Torsten Wierschin Core/Z module (NGL core libs, Group 1) 184 ✅ ancestor
origin/showcase/unittest-and-validate-step-integration-in-lts-svc-s 82da99b41 2026-09-17 Torsten Wierschin Lts Svc (S) migration + unit-test step integration 182 ✅ ancestor
origin/features/migrate-modules-in-lts-proxies a1914cb7d 2026-09-19 Torsten Wierschin Lts/Proxies migration + test suite 186 ✅ ancestor
origin/feature/migrate-and-test-DDS-targets 7cd3e4395 2026-09-21 twi-devel DDS targets migration + tests (merged at ab29b7b2d) 186 ✅ ancestor
origin/bugfix/dds-fix-pre-existing-errors 5501d1e50 2026-09-22 Torsten Wierschin Stub-header updates fixing pre-existing DDS errors 193 ⤵ cherry-picked as b2e787a70 (patch-id-identical; Co-authored-by: Copilot line dropped)
origin/feature/migrate-lts-viewer.md (= origin/feature/qt6-migration-basis-modules) ed9fc51e7 2026-09-23 twi-devel Lts/Viewer migrated to Qt6 194 ✅ ancestor
origin/feature/migrate-lts-tools-d-and-l 2b8f3f02c 2026-09-24 Torsten Wierschin LTS Tools migration incl. Group 9 (R,S,T,V,W) 199 ✅ ancestor (contained in the projects branch — no separate merge needed)
origin/feature/lts-viewer-validation-testing-phase c664611b8 2026-09-24 twi-devel Viewer validation/testing phase; PDM MOC exclusion, record_replay fixes 197 ✅ ancestor (merged at 9c1ac7cbe)
origin/feature/migrate-lts-projects-and-application b18844a20 2026-09-25 Torsten Wierschin LTS Projects (GROUP10) + LTS Application (GROUP11); GROUP10 validation documented 203 ✅ ancestor (base side of the final merge)

Phase 2 — Integration / merge chain (berrux_dev)

Branch Head Date Author Role
feature/qt6-migration-basis-modules-services 881d44f4d 2026-09-23 berrux_dev Residual Lts service sources migrated to generated rtiddsgen API
feature/qt6-migration-basis-modules-merge 36f077bce 2026-09-26 berrux_dev First integration: merged migrate-and-test-DDS-targets (ab29b7b2d) and …-services (5381c65fe); record_replay/fromQVariant + PPM MOC doc (36f077bce)
feature/qt6-migration-basis-modules-merge-viewer-validation 9c1ac7cbe 2026-09-27 berrux_dev Merged lts-viewer-validation-testing-phase into the integration branch (9c1ac7cbe)
feature/qt6-migration-projects-app-tools-viewer-validation 593c221d2 2026-09-28 berrux_dev FINAL: cherry-pick 5501d1e50 → b2e787a70; merged …-viewer-validation into migrate-lts-projects-and-application (593c221d2); resolves 1 content + 24 modify/delete conflicts; 257 commits beyond main

Historical / parallel branches (heads not ancestors of the final branch)

Branch Head Date Author Notes
origin/feature/qt6-migration-signed 5da24495a 2026-08-21 twi-devel Early setup: added qt5-legatus-legacy submodule, signed-commit workflow
origin/feature/qt6-migration-2026-08-21 5ee324f9e 2026-08-22 twi-devel Initial migration kickoff (superseded by later branches)
origin/session-030-build-rti-schutz d76c54614 2026-08-28 twi-devel SIGNAL/SLOT completion + QTextCodec removal (RTI build guard)
origin/entire/checkpoints/v1 2f591c850 2026-09-12 berrux_dev Entire-graph code-graph checkpoint (not migration content)
origin/feature/qt6-migration-basis-modules-berrux ba212f9dc 2026-09-12 berrux_dev TetraIF migration + unit tests (parallel work line; superseded by the integration chain)

Merge Lineage

main (99136e946, 2026-08-13)
│
├─ Historical (Aug): qt6-migration-signed · qt6-migration-2026-08-21 · session-030-build-rti-schutz
│                  · entire/checkpoints/v1 · qt6-migration-basis-modules-berrux
│
├─ Phase 1 (independent module migrations, parallel)
│   ├─ migrate-module-z-only            (Z core)
│   ├─ showcase/…-lts-svc-s             (Svc S + unittest step)
│   ├─ features/migrate-modules-in-lts-proxies
│   ├─ migrate-and-test-DDS-targets ──────────────┐
│   ├─ bugfix/dds-fix-pre-existing-errors ──(cherry-pick b2e787a70)──┐
│   ├─ migrate-lts-viewer.md ≡ qt6-migration-basis-modules (Viewer)  │
│   ├─ migrate-lts-tools-d-and-l (Tools; contained in projects branch)│
│   ├─ lts-viewer-validation-testing-phase ────────┐                 │
│   └─ migrate-lts-projects-and-application (Projects+App) ─────────┐│
│                                                                    ││
└─ Phase 2 (integration chain)                                       ││
    qt6-migration-basis-modules-services                             ││
      └─> qt6-migration-basis-modules-merge                          ││
            [ab29b7b2d: +DDS-targets]  [5381c65fe: +services]        ││
            └─> qt6-migration-basis-modules-merge-viewer-validation  ││
                  [9c1ac7cbe: +lts-viewer-validation-testing-phase]  ││
                  └─> feature/qt6-migration-projects-app-tools-viewer-validation
                        [593c221d2: merge into projects+app base; parents b2e787a70 + 9c1ac7cbe]
                        ★ FINAL RESULT BRANCH (257 commits beyond main)

Merge structure of the final branch (newest first):

  1. 593c221d2 — Merge feature/qt6-migration-basis-modules-merge-viewer-validation into feature/migrate-lts-projects-and-application (parents b2e787a70 + 9c1ac7cbe); signed; 2-line message; sole author/committer.
  2. b2e787a70 — Cherry-pick of 5501d1e50 (stub-header updates; original author Torsten Wierschin preserved; Co-authored-by: Copilot line dropped; signed).
  3. 9c1ac7cbe — Merge feature/lts-viewer-validation-testing-phase into feature/qt6-migration-basis-modules-merge.
  4. 5381c65fe — Merge feature/qt6-migration-basis-modules-services into feature/qt6-migration-basis-modules.
  5. ab29b7b2d — Merge origin/feature/migrate-and-test-DDS-targets into feature/qt6-migration-basis-modules.

Changes Made (Aggregate, by Area)

Per-area detail lives in the in-tree reports; this summary aggregates the changes that landed in the final branch through the branch set:

  1. Core/Z module — NGL core libraries (nglcoreapplication, nglDB, nglTools, nglSettings, NGLLogger, LtsUtilsCore, LtsCoordTrans, LtsCommandLineParser, codegen_base) migrated to Qt6 (Qt6:: targets, no Qt5:: references). Report: BUILD_STATUS_REPORT.md.
  2. DDS / RTI code generation — migration to rtiddsgen 7.7.0 generated API; residual Lts service sources completed against the generated API; stub headers updated to include generated files (cherry-picked 5501d1e50); record_replay fromQVariant for plain enums; PPM MOC exclusion documented. Report: DDS_MIGRATION_REPORT.md, DDS_MIGRATION_STATUS.md, DDS_MIGRATION_SUMMARY.md.
  3. Lts/Proxies — full proxies migration with test suite. Reports: LTS_PROXIES_MIGRATION_REPORT.md, PROXIES_MIGRATION_REPORT.md.
  4. Lts/Viewer — SituationMap/Symbology/DataView/ReportDisplay migrated; ArcGIS-dependent targets (situationMapCommon, advancedSymbology, advancedSymbologyXML) adapted to ArcGIS Maps SDK for Qt 300.0.0; PDM migration cleared the svcPdmClient MOC blocker. Report: VIEWER_MIGRATION_STATUS.md.
  5. LTS Tools (Groups 6–9) — Qt6 migration of all tool groups incl. Group 9 (R,S,T,V,W); 9 base-state mechanical fixes folded in during validation (FindArcGIS APPEND, QUuid ×3, ArcGIS SDK include, logger init, Qt5-isms ×4).
  6. LTS Projects / Application (Groups 10–11) — 9 project plugins and application targets migrated; GROUP10 validation documented. Report: GROUP10_VALIDATION_RESULTS.md.
  7. Merge engineering (final merge) — resolved 1 content conflict (new_docker_build.sh, 3 hunks, union strategy — Group-6 log line kept, text-only) and 24 modify/delete conflicts (resolved as deletions; 24/24 verified by content match against the deleting side's blob).
  8. Test infrastructure — ctest integration across groups; per-service unit tests; LtsDataViewTest viewer hard-requirement test (passes). Report: CTEST-INTEGRATION-STATUS.md, INTEGRATION_TEST_REPORT.md.

Test Results

Run 1 — basic (BUILD_RTI=ON BUILD_GRANTLEE=ON, Groups 1–3)

  • ✅ Build 100 % for Groups 1–3.
  • ✅ ctest: 614 = 584 Passed + 30 Not Run + 0 Failed + 0 Timeout.
  • ✅ svcPdmClient now builds (MOC blocker cleared by the viewer-validation PDM migration).

Run 2 — ArcGIS + Tools + codification (Groups 4–11, +BUILD_WLS=ON)

  • ✅ Groups 1–4: 100 % green.
  • ⚠️ advancedSymbology: 9 base-state mechanical fixes folded in (see Changes Made §5); final base-state blocker: TaskWatcher removed from ArcGIS SDK 300.0.0 (semantic redesign required — reported, not fixed; out of merge scope).
  • ✅ Continuation (Groups 5–11 minus advancedSymbology) built; ctest 615 = 577 Passed + 34 Not Run + 2 Failed + 2 Timeout.
  • ✅ The 2 Failed + 2 Timeout are exactly the 4 documented base-state failures: bld_vwm_test (Failed), bld_vwm_xml_test (Failed), bld_bsm_test (Timeout), taboc_serialtest (Timeout). No new ctest regressions from the merge.
  • ✅ LtsDataViewTest built and PASSED (not in the Not-Run list).
  • ✅ All 34 Not-Run tests are pre-existing classes (e.g. duplicate dds*_smoke/dds*_gtest placeholder registrations from DdsUnitTestsPlaceholder).

Run 3 — viewer-only (--build-viewer-only)

  • ✅ Viewer group 100 %: situationMapCommon, advancedSymbologyXML, LtsDataView, LtsDataViewTest, LtsReportDisplay.
  • ✅ ctest 34 = 1 PASSED (LtsDataViewTest, 1.04 s — hard requirement met) + 33 Not Run (pre-existing viewer-only class) + 0 Failed + 0 Timeout.
  • ✅ Script exit code 8 = ctest "Not Run present" status (expected, not a failure).

Base-state build failures (all proven pre-existing via per-file git provenance)

# Area Failing targets Root cause (all pre-merge)
a LtsSession LtsSession.so link fail → cascades Splash, OperatorApplication, LtsFileDialog, LtsFileDialogTest (no own errors) Empty-namespace stub lts_session_lock_handler.cpp (commit b1ff11043, pre-merge) + Core::Interface::Ftc::create not linked. Legacy tree has a 290-line implementation.
b Qt6 API debt (tools) LogViewer, ProjectSettingsEditor, AdlerWebSocketSimulator, qledline → cascades displayPanelSimulator Base-state Qt6 API debt (Qt::TextColorRole, QtWidgets/QAction misuse, QString::SkipEmptyParts, setMargin)
c Stale generated-DDS naming ddsview, aarApp, ParticipantDataGenerator, tDataSampleGenerator/Receiver Sources use pre-regeneration DDS accessor naming; omg::types::optional misuse
d CnrProxyTester CnrProxyTester mainwindow.ui missing (autouic)
e Apps.json IID checker Ets / Ahtc / Qatar / L400P2 plugins PRE_BUILD LtsAppDescriptorChecker fails: apps.json IIDs (e.g. tln.view) have no matching *_gui_plugin.h; EventTimelineClassic removed pre-merge (92ad7d468)
f 16 missing make targets 5 project plugins, thp_viewer, videoimport, AsmWorkstationCertifier, 8 GROUP7/9 array entries (f1) NGL_COMPILE_RESOURCES contains a return() inside the macro → silently skips the following NGL_ADD_LIBRARY (verified via cmake --trace-source); (f2) thp_viewer disabled (VLC unavailable, pre-merge comment); (f3) videoimport commented out (pre-merge); (f4) AsmWorkstationCertifier skipped (no botan2 in prebuilt image); (f5) 8 CMake array entries use class names instead of actual target names (QLedLine→qledline, QLedMatrix→qledmatrix, Times→ctime/stime, TopicDiscover→topicdiscover, VapixConfig→vapixconfig, SqlBrowser→sqlbrowser, TextEditorTest→textEditorTest, TrajectoryWidget→TrajectoryShader) — the real targets exist and build

Merge-regression check: all failing files have zero diff against the merge base (fd3e5e838) from either parent branch — i.e. none of them were touched by either side of the merge. The merge introduced no regressions.


Technical Challenges & Solutions

Challenge 1: 25 merge conflicts (1 content + 24 modify/delete)

Problem: The two merge sides diverged heavily on the tooling build script and deleted/restructured many files. Solution: Dry run in a throwaway worktree first; new_docker_build.sh resolved with a union strategy across 3 hunks (both sides' additions kept, text-only, script checks re-run: bash -n, --help, unknown-option handling, target sets); the 24 modify/delete conflicts resolved as deletions with a 24/24 content-match verification against the deleting side's blob before staging.

Challenge 2: CMAKE_PREFIX_PATH semicolons mangled by docker bash -c

Problem: Unquoted ; separators were split by the shell, poisoning the build cache (32 configure errors Target "Qt6::Location" not found). Solution: Quote the prefix in the docker command. A fresh build dir with the exact script flags configured cleanly (0 errors), proving cache poisoning was the sole cause. Harmless in practice because the script does rm -rf build4 at every run start.

Challenge 3: NGL_COMPILE_RESOURCES silently drops targets

Problem: 5 project plugins reported "No rule to make target" although their CMakeLists looked complete. Solution: cmake --trace-source proved the macro's internal return() (intended as "macro done") is treated by CMake as return-from-CMakeLists, skipping the subsequent NGL_ADD_LIBRARY. Documented as a base-state blocker (working plugins use NGL_ADD_BIG_RESOURCES); not fixed in this merge (out of scope).

Challenge 4: ArcGIS TaskWatcher removed in SDK 300.0.0

Problem: advancedSymbology uses TaskWatcher; the SDK removed the class with a semantic QFuture redesign. Solution: 9 base-state mechanical fixes folded in (FindArcGIS include-path APPEND, QUuid ×3, SDK include, logger init, Qt5-isms ×4); the TaskWatcher redesign itself is reported as a base-state blocker — a semantic port, not a mechanical fix.

Problem: LtsSession.so fails to link (empty stub lts_session_lock_handler.cpp, pre-merge commit b1ff11043), cascading to Splash/OperatorApplication/LtsFileDialog targets. Solution: Reported as a base-state blocker. Fix = porting the 290-line legacy Qt5 implementation and wiring the Core client — out of merge scope; silently stubbing would hide real behavior.

Challenge 6: ctest exit-code semantics and duplicate placeholder tests

Problem: Exit code 8 ("Not Run present") looks like a failure; 34 Not-Run tests include duplicate same-named dds*_smoke/dds*_gtest registrations against never-built executables (DdsUnitTestsPlaceholder). Solution: Verified the Not-Run set is exactly the pre-existing class (base-state); exit 8 treated as expected status, not a regression signal. Regression criterion = new Failed/Timeout beyond the documented base-state class.

Challenge 7: GPG signing in a submodule with worktree-relative signers file

Problem: gpg.ssh.allowedsignersfile points at ci/allowed_signers (worktree-relative); signing/verification had to be proven end-to-end before committing. Solution: Verified git verify-commit = Good on the cherry-pick (b2e787a70) and the merge commit (593c221d2, ED25519). A pre-existing 8-U signature-gate blocker on the projects side is documented (see Remaining Work).

Challenge 8: Non-incremental build directory

Problem: Diagnostic configure runs polluted the build4 cache. Solution: Confirmed the script deletes and recreates build4 on every run start (line 1196), so each run is fresh; contamination could not affect run results.


Build Instructions

All runs use qt6-after/qt6-migrated-legatus/new_docker_build.sh with the prebuilt image legatus-qt6-prebuilt:latest (mounts the pipeline repo at /workspace, rti_license.dat, and external/ read-only).

cd /home/nkana/repo/qt6-migration-pipeline/qt-migration-legatus/qt6-after/qt6-migrated-legatus

# Run 1 — basic (Groups 1-3), RTI + Grantlee
./new_docker_build.sh ON --grantlee --group1 --group2 --group3 --docker-image legatus-qt6-prebuilt:latest

# Run 2 — ArcGIS + Tools + codification (Groups 4-11), RTI + Grantlee + ArcGIS + Codification + WLS
./new_docker_build.sh ON --grantlee --arcgis --codification \
    --group4 --group5 --group6 --group7 --group8 --group9 --group10 --group11 \
    --cmake_build_flags "-DBUILD_WLS=ON" \
    --docker-image legatus-qt6-prebuilt:latest

# Run 3 — viewer only (skips Groups 1-4, implies --group5 --codification; ctest runs)
./new_docker_build.sh ON --grantlee --arcgis --build-viewer-only \
    --docker-image legatus-qt6-prebuilt:latest

Useful variants: --no-ctest (skip tests), --tests-only (ctest only), --integration-test (integration tests only: test_z_*, bld_*, tab_*, wls_*), --build-prebuilt-image (rebuild the image).

In-container configure is: cmake .. -DBUILD_TESTING=ON -DBUILD_ALL=ON -DBUILD_SV=ON -DBUILD_WS=ON -DBUILD_AAR=ON -DBUILD_RTI=ON -DBUILD_GRANTLEE=ON -DBUILD_ARCGIS=<run> -DBUILD_CODIFICATION=<run> -DBUILD_VIEWER_ONLY=<run 3> -DCMAKE_CXX_STANDARD=17 -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="/opt/Qt/6.10.2/gcc_64;<ArcGIS SDK>;/usr/local".


Dependencies

Qt 6.10.2 (required)

Core, Widgets, Gui, Network, Sql, Xml, Test, Location, Network, Sensors (cmake configs present in the prebuilt image), plus KTextTemplate/Grantlee replacement (BUILD_GRANTLEE).

External

Dependency Version / Note
rtiddsgen (RTI DDS) 7.7.0 — generated code for DDS/RTI types; rti_license.dat mounted
ArcGIS Maps SDK for Qt 300.0.0 — BUILD_ARCGIS=ON (run 2, run 3)
KDReports-qt6 2.3.95 — required for BUILD_CODIFICATION=ON
cmake 4.2.3 (prebuilt image)
botan2 absent in prebuilt image → AsmWorkstationCertifier skipped (base-state)
VLC unavailable → thp_viewer disabled (pre-merge decision)

Remaining Work

High priority

  1. ArcGIS TaskWatcher redesign in advancedSymbology — semantic port to the SDK 300.0.0 QFuture-based API (reported base-state blocker).
  2. LtsSession implementation — port the 290-line legacy implementation of lts_session_lock_handler.cpp and wire Core::Interface::Ftc::create; unblocks the Splash/OperatorApplication/LtsFileDialog cascade.
  3. Merge-regression-free integration is done, but the final branch is NOT pushed (per task instruction) — pushing + the pre-existing 8-U signature-gate fix on the projects side are the next integration steps.

Medium priority

  1. Qt6 API debt in tool sources (LogViewer, ProjectSettingsEditor, AdlerWebSocketSimulator, qledline).
  2. Stale generated-DDS accessor naming (ddsview, aarApp, ParticipantDataGenerator, tDataSampleGenerator/Receiver) — regenerate or adapt to the rtiddsgen 7.7.0 API.
  3. apps.json IID consistency (LtsAppDescriptorChecker): re-add matching *_gui_plugin.h or drop the stale IIDs for Ets/Ahtc/Qatar/L400P2.
  4. CnrProxyTester — restore missing mainwindow.ui.

Low priority

  1. Fix the 8 CMake array entries using class names instead of target names (GROUP7/9) — real targets already build.
  2. Decide whether NGL_COMPILE_RESOURCES' return() is a macro bug (5 plugins silently not built) vs. intended — align with NGL_ADD_BIG_RESOURCES.
  3. Clean up DdsUnitTestsPlaceholder duplicate test registrations; provide botan2 / VLC in the prebuilt image if AsmWorkstationCertifier / thp_viewer should build.
  4. mainwindow.ui-style autouic gaps and the ddsview/aarApp naming follow-ups.

Lessons Learned

  • Prove provenance before fixing: every base-state failure was verified with a per-file git diff --name-only <merge-base>..<branch> check — 0 files touched by either side. This turned "the build is red" into a precise, defensible blocker list instead of speculative merge fixes.
  • Dry-run merges in a worktree: the 1 content + 24 modify/delete conflicts were fully mapped (with 24/24 content-match verification) before the real merge was started.
  • return() inside a CMake macro is CMakeLists-level control flow — a classic silent-target-drop trap; cmake --trace-source is the definitive diagnostic.
  • Quote CMAKE_PREFIX_PATH in docker bash -c — unquoted semicolons are shell word separators, not cmake list separators.
  • Non-incremental build dirs remove an entire class of cache-poisoning bugs — but only if diagnostics use separate build dirs (the script's rm -rf build4 saved the runs).
  • Cherry-pick equivalence is checkable: identical git patch-id --stable proved b2e787a70 ≡ 5501d1e50 content-wise while allowing attribution-line cleanup.
  • Signed commits in a submodule need the worktree-relative allowed_signers file in place; verify with git verify-commit before trusting the pipeline.
  • ctest "Not Run" (exit 8) is a status, not a failure — regression criteria must be defined as new Failed/Timeout beyond the documented base-state class.

Recommendations

For Future Migrations

  • Define the base-state failure class (Failed/Timeout/Not-Run inventory) before merging; it becomes the objective regression gate.
  • Keep one validation Docker image + one build script as the single source of truth; per-run variation only via documented flags (--arcgis, --codification, --build-viewer-only, --cmake_build_flags).
  • Freeze the legacy tree as read-only and record it in every report — it is the reference for provenance checks and stub ports (e.g. LtsSession).
  • Record per-branch FINAL-REPORTs at the pipeline root (as done for each merge prompt) — they make the aggregate summary trivial to compile.
  • Prefer GPG-signed commits from the start of each branch; retrofitting the signers file mid-pipeline creates gate friction (the 8-U blocker).

For the Legatus Merge Specifically

  • Land the final branch (593c221d2) only after (a) the 8-U signature-gate is resolved on the projects side and (b) the two high-priority blockers (TaskWatcher, LtsSession) have an owner or are accepted as known-red with documentation.
  • Add a regression-gate job to CI that re-runs Runs 1–3 on every push and fails only on new Failed/Timeout beyond the documented base-state class.
  • Track the 16 missing make targets as a single follow-up ticket (they are all mechanical: name fixes + macro fix + two disabled subdirs).

Conclusion

✅ The Qt5 → Qt6 6.10.2 migration pipeline is complete at branch level. All 14 independent migration branches were integrated through a 4-stage merge chain into the final branch feature/qt6-migration-projects-app-tools-viewer-validation (593c221d2, 257 commits beyond main, GPG-signed throughout). Three full Docker validation runs (basic, ArcGIS/Tools/codification, viewer-only) confirm that the merge introduced zero build regressions and zero ctest regressions: every red target and every Failed/Timeout test is a documented, git-proven base-state issue. The hard viewer requirement (LtsDataViewTest) passes. The two semantic blockers (ArcGIS TaskWatcher redesign, LtsSession implementation) are reported with root cause and fix scope, and the remaining work is tracked by priority above.

Next steps: push the final branch (currently withheld per task instruction), resolve the 8-U signature gate on the projects side, then assign owners for the two high-priority blockers.


Report generated: 2026-09-28 Final branch: feature/qt6-migration-projects-app-tools-viewer-validation @ 593c221d2 (257 commits beyond main) Build: new_docker_build.sh + legatus-qt6-prebuilt:latest (3 validation runs, all green within the base-state class) Qt Version: 6.10.2 Test Pass Rate: Run 1 584/584 active Passed · Run 2 577/579 active Passed (2 Failed/2 Timeout = base-state) · Run 3 LtsDataViewTest Passed (hard requirement)