Merges main into

This commit is contained in:
torsten committed 2026-10-23 16:57:21 +00:00
commit 24cbe6d107
3707 files changed
+2133515 -3

No files matched your search

@@ -0,0 +1,608 @@
# Strict Qt6 Migration Prompt: Merge of feature/migrate-module-tetraif-only into feature/qt6-migration-projects-app-tools-viewer-validation
This prompt is binding task context. Keep changes minimal, scoped, and reproducible.
The only allowed outcome is a merge commit on
`feature/qt6-migration-projects-app-tools-viewer-validation-tetraif` that contains the full work of
both source branches and preserves the legacy code behavior of every migrated file.
## Required base prompts
Before making changes, read and apply:
- ./prompts/combined-migration-subfolder-rti-compact.prompt.md
- ./prompts/commit-policy.prompt.md (repository mapping, pre-commit checks, per-repo commits)
- ../MODULE_Z_MIGRATION_REPORT.md (all rules and validations in this report are binding for
this merge: compare every changed file against the legacy Qt5 source and prove it is a
migration-only change with no behavior change)
If a base prompt is stricter, follow it. This prompt overrides it only for:
- build variants: use ON variants only for `BUILD_RTI`/`BUILD_GRANTLEE`, never OFF
- commit message format: max 2 lines, single author, no co-author lines (see "Commits")
## Task
Merge these two branches and resolve every conflict without changing code behavior:
- **ours (merge target base):** `feature/qt6-migration-projects-app-tools-viewer-validation`
remote tip at prompt writing (2026-10-05): `43300efaa` ("Merge pull request 'bugfix/fix-warning-issue' (#4) ...")
NOTE: the local branch tip may still point at `593c221d2` (stale). The origin tip moved to
`43300efaa` on the 2026-10-05 fetch (the tip absorbed the Groups 10/11 build fixes + plugin
modules via PR #4). If the local branch still points at `593c221d2`, resync it to
`origin/feature/qt6-migration-projects-app-tools-viewer-validation` before starting.
- **theirs (branch to merge in):** `feature/migrate-module-tetraif-only`
remote tip at prompt writing: `7b090a26c` ("Fix QLedLine QHBoxLayout::setMargin() deprecation for Qt6")
- **merge base:** `d8ec9e8d7` ("Merge pull request 'fix Warning' (#3) ...")
- **result branch:** `feature/qt6-migration-projects-app-tools-viewer-validation-tetraif`
(does not exist yet at prompt writing; create it from
`origin/feature/qt6-migration-projects-app-tools-viewer-validation`)
All work happens in the repository `./qt-migration-legatus` (it is a separate git
repository; never commit its changes into the workspace root or the legacy repository).
## Branches and trees
Working repository:
- `./qt-migration-legatus`
Trees:
- Legacy Qt5 source tree (read-only reference, never modify):
`./qt-migration-legatus/qt5-before/qt5-legatus-legacy`
- Qt6 target tree (the only tree that is modified):
`./qt-migration-legatus/qt6-after/qt6-migrated-legatus`
Before starting:
1. `git fetch origin` in `./qt-migration-legatus`.
2. Verify both remote tips still match the hashes above (`git rev-parse origin/feature/qt6-migration-projects-app-tools-viewer-validation` → `43300efaa`, and `git rev-parse origin/feature/migrate-module-tetraif-only` → `7b090a26c`).
3. If either tip moved, recompute the merge base and re-run the dry-run merge (step 3 of the procedure) before resolving anything.
4. Verify the working tree of `./qt-migration-legatus` is clean (`git status --short`). Do not overwrite uncommitted user changes; if they block safe work, report the blocker.
## What each side contains
Understand both sides before resolving anything. The merge must keep the work of BOTH sides.
**merge-branch side (ours, 3 commits after the merge base, ~414 files, +24949/−10043):**
- `040bdd558` — removed the forward-declaration stub-header directories
(`.forward-declarations/` and `forward-declarations/`): ~262 files changed, mostly
deletions (the `.forward-declarations/include/...` stub headers are gone). This is a
deliberate, committed relocation decision on this branch — the merge must **preserve** it
(do not restore the removed directories or the stub headers they contained).
- `3f7beb3c7` — "Qt6 migration: build fixes for Groups 10/11 + missing plugin modules". The
substantive migration work on this side:
- Qt5→Qt6 API migration (removed/deprecated Qt6 APIs) across Lts Tools and Apps, e.g.
`QAction`→`QActionGroup`, `QAbstractSocket::errorOccurred`, `Qt::SkipEmptyParts`,
`QRandomGenerator`, `QInputDevice::DeviceType`, `QRegularExpression`,
`QLatin1Literal`→`QStringLiteral`, and the SampleModel `m_description`→`description`
rename.
- CMake build fixes:
- root `CMakeLists.txt`: added `Lts/Common` to `CMAKE_AUTOMOC_INCLUDE_DIRECTORIES` so moc
resolves `Q_INTERFACES(ProjectPlugin::Plugin)` for the migrated Projects.
- `cmake/NGLMacros.cmake`: `NGL_COMPILE_RESOURCES` — replaced `return()` (which aborts the
calling `CMakeLists.txt`) with an `if/else/endif`.
- `Lts/Application/OpApp` and `Lts/Application/THP`: guarded the `ArcGISQt5Hack` link with
`$<IF:$<TARGET_EXISTS:ArcGISQt5Hack>,ArcGISQt5Hack,>` (target is absent when the
SituationMap viewer is stubbed); matches `CentralEffectSimulation`.
- `LtsSession`: prefer the in-tree `svcCoreClient` target over a `FIND_LIBRARY` in
`/usr/local/lib`.
- `CnrProxyTester`/`DotMatrixDisplay`: set `AUTOUIC_SEARCH_PATHS` for the `ui/` subdir.
- `TopicDiscover`: link `NGLLogger`.
- Export-header visibility stubs (the build sets `-fvisibility=hidden`; an empty `*_EXPORT`
stub shadows the CMake `GENERATE_EXPORT_HEADER` output and hides the lib's symbols →
`undefined reference`). The stub macro now expands to
`__attribute__((visibility("default")))` (msvc: `__declspec(dllexport)`):
- `include/LtsProjectionWorkstation/ltsprojectionworkstation_export.h` (fixes undefined
reference to `LtsProjectionWorkstation::getInstance` /
`setProjectionOperatorPreset`).
- `include/LtsSession/ltssession_export.h`,
`include/LtsUtilsGuiDds/ltsutilsguidds_export.h` (same pattern).
- Three new plugin modules (copied from legacy) so `LtsAppDescriptorChecker` finds the
`gui:3` IIDs referenced by the Projects' `apps.json`:
- `Lts/Plugins/TakeHomePackageManager/OldTHP` — `gui:3:tpm.man`, `gui:3:tpm.usb`
- `Lts/Plugins/PresentationManagement/Gui/Script/ScriptEditor` — `gui:3:pre.script.edit`
- `Lts/Plugins/Timeline/Gui/EventTimelineClassic` — `gui:3:tln.view`
- `new_docker_build.sh` (ours side): corrected group targets to the actual CMake target
names (GROUP8 `QLedLine`→`qledline`, `QLedMatrix`→`qledmatrix`; GROUP9 `SqlBrowser`→
`sqlbrowser`, `TextEditorTest`→`textEditorTest`, `Times`→`ctime`+`stime`,
`TopicDiscover`→`topicdiscover`+`topicdiscoverexe`, `VapixConfig`→`vapixconfig`,
`WlsRandomPositions`→`wlsRandomPositions`); guarded `LtsReportDisplay` behind
`BUILD_CODIFICATION=ON` (it `RETURN()`s otherwise); commented out modules unavailable in
the prebuilt image (`AsmWorkstationCertifier`/botan2, `TrajectoryWidget`, `VideoImport`,
`thp_viewer`/VLC).
- `43300efaa` — the merge commit (PR #4) that brought the above into this branch.
**theirs side (feature/migrate-module-tetraif-only, 4 commits after the merge base, 14 files, +125/−13):**
The TetraIF module migration. Files:
- `3f8a7eccf` — "Adds rti evaluation licence": `qt6-after/qt6-migrated-legatus/rti_license.dat`
(binary; ours does **not** touch this file, so theirs's version is taken wholesale in the
auto-merge).
- `ab1cf6064` — "Add TetraIF targets to GROUP6 and create compilation tests":
- `new_docker_build.sh` GROUP6: commented out `tDataSampleGenerator`, `tDataSampleReceiver`
("pre-existing Qt6 RTI API issue (method calls vs member access)") and `ddsview`
("pre-existing Qt6 migration issues (QStringBuilder, member naming)"); **added** the three
TetraIF targets `CoPrtCnv`, `PrtCnvLib`, `PrtCnv` so they compile as part of the build
(the "compilation tests" — no separate CTest entries are registered under `TetraIF/`).
- `TetraIF/CMakeLists.txt`: **removed** the `if(BUILD_RTI) ... endif()` guard around the three
`ADD_SUBDIRECTORY(CoPrtCnv/LogView/PrtCnv)` calls, making them build unconditionally.
See "Legacy comparison" — this **restores the legacy behavior** (legacy had no guard).
- `1bcc7e485` — "TetraIF Qt6 migration: Fix build errors for CoPrtCnv, PrtCnv, and LogView":
- `TetraIF/CoPrtCnv/CMakeLists.txt` (dedup of a repeated `find_package(Qt6 COMPONENTS Core QUIET)`),
- `TetraIF/LogView/LogViewTelegramEditModel.hpp` (`#include <QtGui/QAbstractTableModel>` →
`#include <QtCore/QAbstractTableModel>`, the Qt6 module move),
- `TetraIF/PrtCnv/PrtCnvApplication.{cpp,hpp}`, `TetraIF/PrtCnv/PrtCnvBroadcastMgr.{cpp,hpp}`,
`TetraIF/PrtCnv/PrtCnvCentralThread.cpp`.
- `7b090a26c` — "Fix QLedLine QHBoxLayout::setMargin() deprecation for Qt6":
`Lts/Tools/QLedLine/qledline.cpp` (removes the deprecated `m_layout->setMargin(0);`).
- Three repository-root documentation files **added** (ours does not touch them; taken
wholesale): `.entire/agent-guide.md`, `AGENTS.md`, `CLAUDE.md`.
## Known conflict surface (dry run 2026-10-05)
A worktree dry-run merge (`git worktree` at the ours tip + `git merge --no-commit --no-ff
origin/feature/migrate-module-tetraif-only`) reports **"Automatic merge went well"** —
**0 content conflicts and 0 modify/delete conflicts**. The two branches edited
non-overlapping line ranges, so git merges them line-by-line without a textual conflict.
Re-run the dry run after the fetch and treat its output as authoritative; the below is the
expected starting point.
Because the textual merge is clean, the risk is **semantic**, not syntactic. Two files were
touched by BOTH sides and must be verified as a correct union (git can merge line-wise even
when both sides change the same logical region):
1. `qt6-after/qt6-migrated-legatus/new_docker_build.sh`
Both sides edited it. The auto-merged result is the union of:
- **ours:** the `LtsReportDisplay` `BUILD_CODIFICATION` guard (inserted after the GROUP5
`if/else` block, before the "# Group 6" comment), the GROUP7/8/9/11 target-name
corrections and unavailable-module comments.
- **theirs:** the GROUP6 body — the three comment-outs and the three `CoPrtCnv`/`PrtCnvLib`/
`PrtCnv` additions.
These regions do not overlap line-wise, so the union is structurally correct in the
auto-merge. **However there is one semantic decision point** in the GROUP6 body: the
auto-merge keeps theirs's `# ddsview - ...` comment-out (ours never touched that line).
See the `new_docker_build.sh` merge recipe below for the required resolution.
2. `qt6-after/qt6-migrated-legatus/Lts/Tools/QLedLine/qledline.cpp`
**Convergent duplicate.** BOTH sides made the *identical* change: removed
`m_layout->setMargin(0);` (a Qt5-deprecated call removed for Qt6). Verified: the
auto-merged blob is byte-identical to both the ours and the theirs blob. No decision
needed — the merge is unambiguous. Keep the single removal.
Auto-merged (theirs-only files, no both-side touch — no conflict, taken from theirs):
- `qt6-after/qt6-migrated-legatus/rti_license.dat` (binary)
- `qt6-after/qt6-migrated-legatus/TetraIF/CMakeLists.txt`
- `qt6-after/qt6-migrated-legatus/TetraIF/CoPrtCnv/CMakeLists.txt`
- `qt6-after/qt6-migrated-legatus/TetraIF/LogView/LogViewTelegramEditModel.hpp`
- `qt6-after/qt6-migrated-legatus/TetraIF/PrtCnv/PrtCnvApplication.cpp`
- `qt6-after/qt6-migrated-legatus/TetraIF/PrtCnv/PrtCnvApplication.hpp`
- `qt6-after/qt6-migrated-legatus/TetraIF/PrtCnv/PrtCnvBroadcastMgr.cpp`
- `qt6-after/qt6-migrated-legatus/TetraIF/PrtCnv/PrtCnvBroadcastMgr.hpp`
- `qt6-after/qt6-migrated-legatus/TetraIF/PrtCnv/PrtCnvCentralThread.cpp`
- `.entire/agent-guide.md`, `AGENTS.md`, `CLAUDE.md` (repository-root additions)
## Conflict resolution rules
These rules exist to guarantee: the merged tree keeps both branches' functionality and no
file's behavior deviates from the legacy Qt5 behavior beyond the approved
Qt6/C++17/rtiddsgen adaptations.
General:
- Resolve semantically, never mechanically. For every both-side file read four versions:
the merge-base version, ours, theirs, and the legacy Qt5 equivalent
(`./qt-migration-legatus/qt5-before/qt5-legatus-legacy` at the same relative path; for
`new_docker_build.sh` there is no legacy counterpart — it is pure Qt6 build machinery — so
use the merge-base version as the third reference). The resolution must keep both sides'
approved adaptations.
- Never take `ours` or `theirs` wholesale for a both-side file unless you prove the losing
side had no unique changes: `git diff <merge-base>..theirs -- <file>` (or `..ours`) must
show nothing that the kept version lacks. Record the proof in the final report.
- A merge commit must not drop functionality of either branch: every target, dependency,
test registration, docker build option, and code fix present on one side must be present
(or superseded by an equivalent) in the merged tree.
- No behavior-changing edits beyond the merge itself. No refactoring, no style cleanup, no
warning suppression, no new features.
`new_docker_build.sh` (the single semantic-union file) — required merge recipe:
Keep from the ours side (none of this may be lost):
- the `LtsReportDisplay` `BUILD_CODIFICATION=ON` guard block (it sits after the GROUP5
`if/else` block and before the "# Group 6" comment)
- GROUP7: `# AsmWorkstationCertifier - requires botan2 ...` (commented, target not generated)
- GROUP8: the lowercase target names `qledline`, `qledmatrix`
- GROUP9: the corrected target names `sqlbrowser`, `textEditorTest`, `ctime`, `stime`,
`topicdiscover`, `topicdiscoverexe`, `vapixconfig`, `wlsRandomPositions`, plus the
`# TrajectoryWidget - standalone sub-project ...` and `# VideoImport - subdir commented out ...`
comments
- GROUP11: the `# thp_viewer - Lts/Application/THP subdir commented out (VLC ...)` comment
Keep from the theirs side (none of this may be lost):
- GROUP6: the three new TetraIF targets `CoPrtCnv`, `PrtCnvLib`, `PrtCnv` — these **must**
stay active; they are the purpose of the merge
- GROUP6: the `# tDataSampleGenerator - pre-existing Qt6 RTI API issue ...` and
`# tDataSampleReceiver - ...` comment-outs, **unless** the GROUP6 validation build proves
they now compile (see the decision rule below)
GROUP6 decision rule (the `ddsview` / `t*` semantic decision):
- The auto-merge leaves `# ddsview - pre-existing Qt6 migration issues ...` commented out
(theirs's line; ours never touched it). **But the ours tree builds and validates
`ddsview`** (the ours-side `new_docker_build.sh` leaves `ddsview` active in GROUP6, and it
was confirmed to compile and run on the ours side). Dropping it would silently remove
ours-side validation coverage, violating "keep both sides' work / no behavior change".
- Resolution: **re-activate `ddsview`** in the merged GROUP6 (remove the theirs comment-out
for that line), keep the `CoPrtCnv`/`PrtCnvLib`/`PrtCnv` additions, and **verify** in the
`--group6` validation run that `ddsview` still compiles (and that its topic-type plugins,
if the app is exercised, load). If — and only if — the validation build shows `ddsview`
genuinely failing in the merged tree, keep it commented and record the exact build error.
- For `tDataSampleGenerator` / `tDataSampleReceiver`: keep them commented **only if** they
fail to compile in the merged `--group6` run (the "pre-existing Qt6 RTI API issue" theirs
recorded). If the ours-side migration already fixed those sources and they compile,
re-activate them and record the evidence. Decide from the build result, not by guesswork.
Post-resolution script checks (record in the final report):
- `bash -n` on the host script and on the extracted container-side script
- `--help` renders and lists the `--group6`, `--group10`, `--group11` options (and the full
`--group1`..`--group11` set); an unknown option is still rejected
- target-set check: the merged GROUP6 array contains `CoPrtCnv`, `PrtCnvLib`, `PrtCnv`; the
ours-side GROUP7/8/9/11 target names and comments are present; the `LtsReportDisplay`
`BUILD_CODIFICATION` guard block is present; the container-side script still starts with
`set -euo pipefail`
Modify/delete conflicts: none in the dry run (the theirs side only adds the 3 repo-root docs
and edits files; it deletes nothing). Still run the deletion-guard sweep below before
resolving, so no ours-side deletion is missed:
```bash
git diff --diff-filter=D --name-only <merge-base>..origin/feature/migrate-module-tetraif-only |
while IFS= read -r f; do
if git cat-file -e "origin/feature/qt6-migration-projects-app-tools-viewer-validation:$f" 2>/dev/null; then
echo "KEEP $f"
else
echo "deleted-on-both-sides $f"
fi
done
```
Expected result: empty (the theirs side deletes no files). If any `KEEP` line appears, it is
a file that must be present in the final merge tree with the ours-side content
(`git checkout --ours -- <file>`); every `deleted-on-both-sides` line may stay deleted.
Record the full sweep output in the final report.
CMake conflicts: none in the dry run (the only both-side CMake touch is `new_docker_build.sh`
above; the `TetraIF/*CMakeLists.txt` edits are theirs-only). If the re-run dry run shows a new
CMake conflict: take the union of both sides' targets, dependencies, include directories, and
link libraries. After resolving, verify with a fresh configure that both sides' targets exist
(`cmake --build … --target help`, or the docker script's `--group6`/`--group10`/`--group11`
options).
## Mandatory build variants
Only these variants are valid:
- `BUILD_RTI=ON`
- `BUILD_GRANTLEE=ON`
Forbidden: `BUILD_RTI=OFF`, `BUILD_GRANTLEE=OFF`.
- Do not implement, fix, preserve, test, or validate OFF variants of `BUILD_RTI`/`BUILD_GRANTLEE`.
- Do not add CMake logic, tests, stubs, or fallbacks for those OFF variants.
- Validation must use `BUILD_RTI=ON` and `BUILD_GRANTLEE=ON`.
- The theirs-side change that removes the `if(BUILD_RTI)` guard around the TetraIF
`ADD_SUBDIRECTORY` calls is **not** an OFF-variant implementation; it restores the legacy
unconditional build (see "Legacy comparison"). It is harmless for the mandated `BUILD_RTI=ON`
build and must be preserved.
## Preservation rules
- Preserve the ours-side forward-declaration removal (`040bdd558`): do not restore the removed
`.forward-declarations/` / `forward-declarations/` directories or the stub headers they
contained — on either side.
- Preserve the ours-side Groups 10/11 build fixes, the three added plugin modules, and the
`new_docker_build.sh` target-name corrections (see "What each side contains").
- Preserve the theirs-side TetraIF migration: the three TetraIF targets in GROUP6, the
`TetraIF/*` build fixes, the `QLedLine` deprecation fix, the `TetraIF/CMakeLists.txt`
guard removal, the `rti_license.dat` evaluation licence, and the three repo-root doc files.
- Preserve the ON-variant-only decisions already made on both branches.
## Stubs and forward declarations
- The ours side (`040bdd558`) removed the forward-declaration stub-header directories
(`.forward-declarations/include/...`, `forward-declarations/...`). Preserve that removal:
the merged tree must NOT contain those directories or the stub headers they held.
- Do not create new stubs as replacements for real RTI, ndsgen, KTextTemplate, or Grantlee
outputs in ON builds.
- If the theirs-side TetraIF migration needs any compatibility or forward declaration, it must
follow the current relocation scheme already established on the ours side (not a new
stub-directory), and be reported.
- Report every stub/forward declaration that is moved, removed, or newly referenced.
## Qt link rules
No active target in the merged tree may link Qt5 imported targets.
Search the merged tree for and fix active uses of: `Qt5::`, `find_package(Qt5`, `QT5_`,
`Qt5Core`, `Qt5Widgets`, `Qt5Network`.
Regression check specific to this merge: the theirs side touched
`TetraIF/CoPrtCnv/CMakeLists.txt` (a `find_package(Qt6 COMPONENTS Core QUIET)` dedup) and
`TetraIF/CMakeLists.txt` (guard removal). After the merge, re-run the Qt5 search over ALL
files touched by the merge, not just the both-side hunks; the legacy `QT5_WRAP_UI` /
`QT5_ADD_RESOURCES` function-name calls (compat shim) are allowed and pre-exist on both sides —
imported-target links are not.
## Legacy comparison (required validation step)
This step proves the merge did not change code behavior.
For every both-side file and for each theirs-side file you keep:
1. Read the legacy Qt5 source at the same relative path in
`./qt-migration-legatus/qt5-before/qt5-legatus-legacy`. If the file does not exist there
(pure Qt6 build machinery — expected for `new_docker_build.sh`, `TetraIF/CMakeLists.txt`
guard, `rti_license.dat`), say so and compare against the merge base instead.
2. Produce three diffs: merge-base vs legacy (or: skip with justification), ours vs
merge-base, theirs vs merge-base.
3. Produce the audit diff: merged result vs merge base.
4. Classify every hunk of the audit diff into exactly one category:
- `qt6-api`: mandatory Qt5→Qt6 API adaptation
- `rtiddsgen-api`: generated-API adaptation
- `build`: CMake/docker/test-infra change with no runtime semantics
- `merge-union`: line present because both branches required it
- `semantic-change`: anything else
5. Every `semantic-change` hunk is a failure of this merge unless you can point to the
legacy source line that implements the same behavior. Fix it back to the legacy
semantics (with approved adaptations) or report it as a blocker. Do not silently accept
`semantic-change` hunks. (For `new_docker_build.sh`, `build`/`merge-union` are the expected
categories; a `semantic-change` there means a behavior of one side's script was silently
dropped — the `ddsview`/`t*` GROUP6 decision rule exists to catch exactly this.)
6. Record the per-file hunk classification (counts per category; list every
`semantic-change` hunk explicitly) in the final report.
Pre-verified legacy equivalences (confirm, do not re-derive from scratch):
- **`TetraIF/CMakeLists.txt` (theirs guard removal) is a legacy RESTORATION, not a behavior
change.** Legacy `qt5-before/qt5-legatus-legacy/TetraIF/CMakeLists.txt` has the three
`ADD_SUBDIRECTORY(CoPrtCnv/LogView/PrtCnv)` calls **without** any `if(BUILD_RTI)` guard.
The merge-base tree ADDED the guard during migration; the theirs side removes it, returning
to the legacy unconditional build. Classify the guard-removal hunk as `build` (legacy
restoration), not `semantic-change`.
- **`Lts/Tools/QLedLine/qledline.cpp`** — both sides remove the Qt5-deprecated
`m_layout->setMargin(0);` (legacy Qt5 had it; Qt6 deprecated it). Both-side change is
convergent and identical; the merged result matches the approved Qt6 adaptation.
- **`TetraIF/LogView/LogViewTelegramEditModel.hpp`** — `QtGui/QAbstractTableModel` →
`QtCore/QAbstractTableModel` is the Qt6 module relocation of that class (`qt6-api`).
## Code generation rules
If generated files are required (not expected for this merge):
- reconstruct the real legacy generation flow
- generate into the build tree
- consume from the build tree
- list complete OUTPUT and BYPRODUCTS
- set correct DEPENDS and MAIN_DEPENDENCY where useful
- use deterministic WORKING_DIRECTORY
- use VERBATIM
- wire generated sources with target_sources
- wire generated include dirs with target_include_directories
- ensure compilation depends on generation
- ensure incremental rebuilds trigger on input/template changes
Never commit generated .idl, .h, .hpp, or .cpp outputs. Never consume generated outputs from the
source tree. Never fabricate generated outputs.
## Tests
- Both sides' test suites must build and run; this merge adds no new feature tests. The
theirs-side "compilation tests" are the TetraIF targets (`CoPrtCnv`, `PrtCnvLib`, `PrtCnv`)
compiling as part of GROUP6 — no separate CTest entries are registered under `TetraIF/`.
- If a conflict resolution changed C++ semantics (it should not), add CTest tests under
`./qt-migration-legatus/qt6-after/qt6-migrated-legatus/tests/` that pin the legacy behavior,
registered with CTest, running with `BUILD_RTI=ON` and `BUILD_GRANTLEE=ON`,
policy-compatible names (`test_<name>.cpp`, …).
- No OFF-variant tests of `BUILD_RTI`/`BUILD_GRANTLEE`. No host-local paths.
## Docker and CI
Authoritative migration Dockerfile:
- `./app/Dockerfile`
Authoritative validation script (single script):
- `./qt-migration-legatus/qt6-after/qt6-migrated-legatus/new_docker_build.sh`
Validation container expectations:
- repository root at `/workspace` (the script's documented mount path)
- external dependencies under `/workspace/external` (including `external/rti_connext_dds-7.7.0`)
- `./rti_license.dat` available if RTI requires it — note the theirs side updates
`qt6-after/qt6-migrated-legatus/rti_license.dat` (evaluation licence); the merged tree takes
that version
- no developer-local paths
Jenkins CI must be able to discover and run the merged test set. Inspect and minimally update
only if needed:
- `./qt-migration-legatus/ci/Dockerfile.*`
- `./qt-migration-legatus/ci/check_pr_policies.py`
## Required procedure
1. Read the base prompts (incl. `MODULE_Z_MIGRATION_REPORT.md`). Run `git fetch origin` and verify both remote tips and the merge base (incl. the `593c221d2`→`43300efaa` resync note above).
2. Create/checkout `feature/qt6-migration-projects-app-tools-viewer-validation-tetraif` from `origin/feature/qt6-migration-projects-app-tools-viewer-validation` in `./qt-migration-legatus` (working tree must be clean).
3. Re-run the dry-run merge in a throwaway worktree; confirm the conflict list (expected: 0 textual conflicts, but the 2 both-side files `new_docker_build.sh` and `qledline.cpp` must be semantic-unioned per the recipe).
4. Run the real merge: `git merge --no-ff origin/feature/migrate-module-tetraif-only` (do not auto-commit; resolve first).
5. Run the deletion-guard sweep and resolve the both-side files one file at a time using the four-version method and the `new_docker_build.sh` merge recipe above (re-activate `ddsview`; keep `CoPrtCnv`/`PrtCnvLib`/`PrtCnv`; keep the `t*` comment-outs only if they fail to build).
6. Run the legacy comparison audit (previous section) over every resolved/edited file and each kept theirs-side file.
7. Run the regression checks: Qt5 links, stub/forward-declaration preservation (ours-side removal intact), ON-variant-only CMake, docker script integrity (`bash -n`, `--help`, GROUP6/7/8/9/11 target-set and `LtsReportDisplay`-guard checks), `TetraIF/CMakeLists.txt` guard removal.
8. Validate in Docker with `BUILD_RTI=ON` and `BUILD_GRANTLEE=ON` — all three runs below (the `--group6` run is what proves the `ddsview`/`t*` decision and the TetraIF targets).
9. Run CTest in each validated build (executed as part of the docker runs).
10. Check Jenkins/policy compatibility.
11. Create the merge commit (see Commits).
12. Report factual status.
Do not push. The merge result stays local on
`feature/qt6-migration-projects-app-tools-viewer-validation-tetraif` until the user says
otherwise.
## Required validation
The `new_docker_build.sh` script accepts `--cmake_build_flags "<flags>"` (space-separated `-D`
flags, appended to the in-container configure) and `--group1`..`--group11` (defaults:
GROUP1/2/3 ON, GROUP4–11 OFF). Use the standard cmake build flags:
```
--cmake_build_flags "-DUSE_IPO=ON -DUSE_UNITY_BUILD=ON -DGUEZ_MODE=ON -DBUILD_WLS=ON -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/"
```
(These match the user's mandated build configuration. If `USE_UNITY_BUILD` is a no-op in this
CMake tree — the real option is the plural `USE_UNITY_BUILDS` — note it in the report but keep
passing the user's flag verbatim so the run is reproducible.)
From `./qt-migration-legatus/qt6-after/qt6-migrated-legatus`, run (in order):
```bash
# 1. Baseline default run (groups 1–3: DDS core, migration_tests, migrated-service set)
BUILD_RTI=ON BUILD_GRANTLEE=ON ./new_docker_build.sh \
--cmake_build_flags "-DUSE_IPO=ON -DUSE_UNITY_BUILD=ON -DGUEZ_MODE=ON -DBUILD_WLS=ON -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/"
# 2. Theirs-side contribution — TetraIF module (GROUP6): proves the new targets
# CoPrtCnv / PrtCnvLib / PrtCnv compile, and decides ddsview / tDataSample* activation
BUILD_RTI=ON BUILD_GRANTLEE=ON ./new_docker_build.sh --group6 \
--cmake_build_flags "-DUSE_IPO=ON -DUSE_UNITY_BUILD=ON -DGUEZ_MODE=ON -DBUILD_WLS=ON -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/"
# 3. Ours-side contribution — LTS Projects + LTS Application (GROUP10/11)
BUILD_RTI=ON BUILD_GRANTLEE=ON ./new_docker_build.sh --group10 --group11 \
--cmake_build_flags "-DUSE_IPO=ON -DUSE_UNITY_BUILD=ON -DGUEZ_MODE=ON -DBUILD_WLS=ON -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/"
```
Optionally, a single comprehensive run to confirm the merged script executes end to end:
```bash
BUILD_RTI=ON BUILD_GRANTLEE=ON ./new_docker_build.sh --group1 --group2 --group3 --group4 --group5 --group6 --group7 --group8 --group9 --group10 --group11 \
--cmake_build_flags "-DUSE_IPO=ON -DUSE_UNITY_BUILD=ON -DGUEZ_MODE=ON -DBUILD_WLS=ON -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/"
```
If a direct clean build is useful, use:
```bash
cmake -S /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus -B /workspace/build-merge-tetraif-rti-on-grantlee-on -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_RTI=ON -DBUILD_GRANTLEE=ON -DUSE_IPO=ON -DGUEZ_MODE=ON -DBUILD_WLS=ON -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/
cmake --build /workspace/build-merge-tetraif-rti-on-grantlee-on --parallel --target CoPrtCnv PrtCnvLib PrtCnv ddsview OperatorApplication aarApp
ctest --test-dir /workspace/build-merge-tetraif-rti-on-grantlee-on --output-on-failure
```
CTest baseline: ctest exits with code 8 when tests are "Not Run". A pre-existing set of Not
Run tests (for example nglcomp_test, NGLToolsQtSmoke, test_nglpdfwidget,
GrantleeParserSmoke, lts_coord_trans_unit_test, utils_test, aes_crypt_test, and — when a
group's targets are not in the run's target list — that group's dds/`_gtest` variants) belongs
to sibling targets or OFF groups outside the run's target list and is not a failure. Treat
only `***Failed` entries as failures. Do not widen this exception to skip real failures, and do
not add missing sibling targets to fix the exit code. If a previously passing test becomes
Not Run or Failed after the merge, that is a merge regression: fix it or report it as a blocker.
In the `--group6` run, `CoPrtCnv`, `PrtCnvLib`, and `PrtCnv` MUST build — if they do not, that
is a merge regression (the theirs-side build fixes were not applied correctly): fix it or
report it as a blocker.
Do not run or validate OFF variants of `BUILD_RTI`/`BUILD_GRANTLEE`.
## Commits
- Single author: the user's git identity. The user is the only author; do not add any co-author,
co-authored-by, or bot attribution lines of any kind.
- Commit message: maximum 2 lines (one subject line plus at most one short body line), no
blank-line separators, no extra metadata.
- Merge commit subject example (2 lines max):
`Merge feature/migrate-module-tetraif-only into feature/qt6-migration-projects-app-tools-viewer-validation`
body line: `Resolves 0 textual conflicts; unions new_docker_build.sh (TetraIF GROUP6 targets + ddsview) and keeps the qledline convergent fix; validates with BUILD_RTI=ON BUILD_GRANTLEE=ON.`
- If a conflict resolution requires an additional fix commit on top of the merge commit, the
same 2-line / single-author / no-co-author rules apply.
- Follow `./prompts/commit-policy.prompt.md` for repository mapping and pre-commit checks. If
it requires signed commits and signing is not configured in this repository context, stop
and report the exact reason instead of committing unsigned.
## Success criteria
Success requires:
- `feature/qt6-migration-projects-app-tools-viewer-validation-tetraif` contains a merge commit
with both parents `origin/feature/qt6-migration-projects-app-tools-viewer-validation` (or its
verified successor tip) and `origin/feature/migrate-module-tetraif-only` (or its verified
successor tip)
- the two both-side files resolved with the four-version method + recipe: `new_docker_build.sh`
(union of ours's GROUP5/7/8/9/11 fixes + LtsReportDisplay guard and theirs's GROUP6 TetraIF
additions; `ddsview` re-activated and verified; the `t*` comment-outs kept only if they fail
to build) and `qledline.cpp` (convergent identical removal kept)
- deletion-guard sweep run and its output recorded (expected: empty)
- both branches' functionality preserved: ours's Groups 10/11 build fixes, three plugin
modules, `new_docker_build.sh` target corrections, and forward-declaration removal; theirs's
TetraIF targets + build fixes, `TetraIF/CMakeLists.txt` guard removal, `QLedLine` deprecation
fix, `rti_license.dat` evaluation licence, and the three repo-root doc files
- legacy comparison audit done for every resolved file and each kept theirs-side file; zero
unexplained `semantic-change` hunks; the `TetraIF/CMakeLists.txt` guard removal classified
as a legacy restoration
- configure, build, and CTest pass with `BUILD_RTI=ON` and `BUILD_GRANTLEE=ON` in all three
validation runs (baseline, `--group6`, `--group10 --group11`)
- `new_docker_build.sh` runs the merged test set and fails on test failure; the `--group6` run
builds `CoPrtCnv`, `PrtCnvLib`, `PrtCnv` and (per the decision rule) the correct set of
`ddsview`/`t*` targets
- Jenkins/policy discovery accepts the merged test set
- no active Qt5 imported target links remain in the merged tree
- generated outputs are build-tree only, freshly produced, never committed or consumed from the
source tree
- no fake generated files, dummy files, mocks, placeholders, or stubbed generated outputs
- the ours-side forward-declaration removal is preserved (the removed directories are not
restored)
- no OFF-variant logic, tests, or stubs introduced for `BUILD_RTI`/`BUILD_GRANTLEE`
- no push performed
## If blocked
Do not fake success. Report:
- failing command
- key error output
- affected file/branch
- category: project, path, merge, CMake, Qt API, codegen, Docker, RTI/license, Grantlee/KTextTemplate, test, CTest, Jenkins CI, stub relocation, or environment
- which side (ours/theirs) the problematic hunk came from
- what was resolved safely
- what remains blocked
- whether stale artifacts were ruled out
- whether generated files were involved
- exact missing files, targets, or generator step
- whether tests and CTest integration succeeded
- whether Docker validation and Jenkins discovery succeeded
- the legacy comparison status for the unresolved files
- the GROUP6 `ddsview`/`t*` decision: which target the build result forced, and the evidence
## Final report
Keep it short. Include:
- status: validated, partially validated, or blocked
- merge commit hash, both parents, branch name
- per-both-side-file resolution: file, method (union / four-version semantic / convergent),
and the one-line reason
- `new_docker_build.sh` merge evidence: ours-side target-set check (GROUP7/8/9/11 intact,
LtsReportDisplay guard present), theirs-side feature list (GROUP6 `CoPrtCnv`/`PrtCnvLib`/
`PrtCnv` present), and the GROUP6 `ddsview`/`t*` decision with its build evidence, plus the
post-resolution script checks
- deletion-guard sweep result (expected: empty)
- legacy comparison audit summary: per-file hunk counts by category, and every
`semantic-change` hunk with its justification or fix (incl. the `TetraIF/CMakeLists.txt`
guard-removal legacy restoration)
- files changed beyond the both-side set (expected: only the auto-merged theirs-side files)
- Docker and Jenkins CI changes
- Qt5 references removed or remaining
- confirmation that the ours-side forward-declaration removal was preserved and the theirs-side
TetraIF guard removal was kept
- exact validation commands and results for all three runs
- remaining blockers or risks
@@ -0,0 +1,439 @@
# Strict Qt6 Migration Prompt: ArcGIS 300 Symbology — verify & complete the SituationMap + AdvancedSymbology migration
This prompt is binding task context. Keep changes minimal, scoped, and reproducible.
The only allowed outcome is a fully-verified ArcGIS-300 symbology migration in
`qt6-after/qt6-migrated-legatus` in which every migrated symbology file preserves the
legacy Qt5 behavior **except** for the approved Qt5→Qt6 / ArcGIS-Maps-SDK-300 API
adaptations. No behavior change is allowed in the ON-variant (validated) build.
ArcGIS version in use: **ArcGIS Maps SDK for Qt 300.0.0**
(`external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/qt300.0.0/sdk`).
## Required base prompts
Before making changes, read and apply:
- ./prompts/combined-migration-subfolder-rti-compact.prompt.md
- ./prompts/commit-policy.prompt.md (repository mapping, pre-commit checks, per-repo commits)
If a base prompt is stricter, follow it. This prompt adds:
- build variants: ON variants only for `BUILD_RTI`/`BUILD_GRANTLEE`; validation uses
`BUILD_ARCGIS=ON` (this is **not** an RTI/Grantlee OFF variant — the prohibition on OFF
RTI/Grantlee does not apply to ArcGIS)
- scope: the symbology subsystem (SituationMap + AdvancedSymbology), ArcGIS 300.0.0
## Task
Verify — and where the migration is incomplete or diverges from legacy, complete — the
ArcGIS 300 migration of the symbology subsystem:
- the SituationMap viewer's military (SIDC) symbology: `Symbology/`, `SymbologyImpl/`,
`SymbologyXML/` (the pure-Qt SIDC codec/builder/dictionary **plus** the Esri
dictionary-symbol processors that parse ArcGIS `.style` dictionaries)
- the ArcGIS map layer: `SituationMap/Map/` (now on the new ArcGIS Maps SDK for Qt 300.0.0)
- the AdvancedSymbology plugin: `Lts/Plugins/AdvancedSymbology/` (symbol editor, symbol
proxy, data plugin, helper renderer)
- the one remaining ArcGIS-dependent service file:
`Lts/Services/CentralEffectSimulation/Plugins/Explosions/expand_polygon.cpp`
For every file in scope, diff it against the legacy Qt5 tree and prove each hunk is
migration-only (or restore it to the legacy semantics with approved adaptations, or report
a blocker).
## Branches and trees
Working repository (a separate git repo; never commit its changes into the workspace root
or the legacy repository):
- `./qt-migration-legatus`
Trees:
- Legacy Qt5 source tree (read-only reference, never modify):
`./qt-migration-legatus/qt5-before/qt5-legatus-legacy`
- Qt6 target tree (the only tree that is modified):
`./qt-migration-legatus/qt6-after/qt6-migrated-legatus`
Working branch: the dedicated ArcGIS-300 symbology branch the user created for this work
(verify its name with `git branch --show-current`; do not conflate it with the main
migration branch).
Before starting:
1. `git fetch origin` in `./qt-migration-legatus`.
2. Confirm the working tree state with `git status --short`. Known state at prompt writing
(2026-10-06): the main worktree is on
`feature/qt6-migration-projects-app-tools-viewer-validation-tetraif` at `1e07bf76b`
("Add ddsview topic-type-plugin deps to GROUP6") with **two uncommitted files** —
`qt6-after/qt6-migrated-legatus/new_docker_build.sh` (the `ensure_database` step) and
`qt6-after/qt6-migrated-legatus/tests/CMakeLists.txt` (10 `migration_tests` target-guard
fixes). Do not lose these: if they are not part of this task, commit or stash them on
their own branch first; do not fold unrelated changes into the symbology commit.
3. Confirm both trees exist and that the ArcGIS SDK 300.0.0 directory exists at the path
below. If the working tree has unrelated uncommitted changes that block safe work,
report the blocker.
## What is already established (verified 2026-10-06 — starting state; re-verify cheaply)
Treat the following as the verified starting state. Re-run the cheap checks to confirm the
current state, but do not re-derive the whole picture.
- **The migration STUBBED almost all ArcGIS.** Legacy `Lts/Viewer` uses the OLD ArcGIS
Runtime SDK (100.x) with **399** `#include <arcgis/...>`. The migrated tree has **11**
arcgis includes total, all in:
- `Lts/Viewer/SituationMap/Map/situation_map_utils.h` (SceneViewTypes.h, Error.h)
- `Lts/Viewer/SituationMap/Map/situation_map_utils.cpp` (CoreTypes.h, MapTypes.h,
Viewpoint.h, Camera.h, arcgisversion.h)
- `Lts/Viewer/SituationMap/Map/map_initializer.cpp` (arcgisversion.h)
- `Lts/Viewer/SituationMap/Map/layer_factory.h` (arcgisversion.h)
- `Lts/Services/CentralEffectSimulation/Plugins/Explosions/expand_polygon.cpp`
(PolygonBuilder.h, GeometryEngine.h)
- `Lts/Viewer/SituationMap/ElevationMap/` (**7 files** in legacy) is **removed** entirely in
the migrated tree. Do not restore it unless this task explicitly requires it.
- The SIDC symbology (`Symbology/`, `SymbologyImpl/`, `SymbologyXML/`) is **pure Qt** —
**zero** arcgis includes. The ArcGIS dependency is confined to the map layer and the one
service file above.
- The migrated arcgis includes use the **new 300.0.0 header names** (`MapTypes.h`,
`Viewpoint.h`, `Camera.h`, `CoreTypes.h`, `SceneViewTypes.h`, `PolygonBuilder.h`,
`GeometryEngine.h`, `arcgisversion.h`) and keep the `Esri::ArcGISRuntime::` namespace
(e.g. `Esri::ArcGISRuntime::SymbolStyleSearchResult` in
`SymbologyImpl/esri_dictionary_processor.cpp`). The **include style is inconsistent**:
some keep the `arcgis/` prefix (`#include <arcgis/Viewpoint.h>`), some drop it
(`#include <TaskWatcher.h>`). This must be reconciled (see step 6 of the procedure).
- **Audit baseline (2026-10-06, CRLF-ignored diff of files present in both trees):**
- SituationMap: **96** common source files differ, ~1149 changed lines, all migration-only
so far.
- AdvancedSymbology: **37** common source files differ (no added/removed source files).
- The Esri dictionary processors (`esri_dictionary_processor*.cpp`) changed only includes
(`#include <arcgis/X.h>` → `#include <X.h>`, Qt include-path churn,
`qAsConst`→`std::as_const`); the Esri types and symbol-search logic are unchanged.
## Scope (the files to audit)
Audit, diff-vs-legacy, and classify **every** source file in:
1. `Lts/Viewer/SituationMap/Symbology/` — SIDC codec/builder/dictionary/definitions
(`sidc_codec.*`, `sidc_builder*.*`, `symbol_dictionary*.*`, `symbol_properties.*`,
`symbol_result.*`, `sidc_definitions.*`, `bulk_renderer.*`, `property_result.*`,
`result_watcher.*`, `symbol_data_to_render*.*`, `symbology_type.*`, …).
2. `Lts/Viewer/SituationMap/SymbologyImpl/` — `esri_dictionary_processor*.cpp/.h`
(`esri_dictionary_processor`, `..._app6`, `..._app6d`, `..._mil2525d`),
`base_symbol_model.*`, `symbol_dictionary_impl.*`, `symbol_extension_renderer.*`,
`advanced_symbology_logging.*`.
3. `Lts/Viewer/SituationMap/SymbologyXML/` — `symbol.*`, `symbol_reader.*`,
`symbol_writer.*`, `symbol_exporter.*`, `symbol_table.*`, `pixmap_symbol_cache.*`,
`symbol_custom_graphics_item_group.*`, `attribute_data.h`, `symbol_types.h`,
`xml_symbol_codec.h`, `Gui/symbol_dialog.*`.
4. `Lts/Viewer/SituationMap/Map/` — the ArcGIS map layer (57 files): `map.*`,
`map_initializer.*`, `layer_factory.h`, `situation_map_utils.*`, `camera.*`,
`fill_style.*`, `line_style.*`, `geometry_model_renderer.*`, `object_container.*`,
`object_factory.*`, `map_settings.*`, `operator_map_settings.*`, `map_notifier.*`,
`bounding_box.*`, `grid.h`, `measurement.h`, … and every sibling present in the dir.
5. `Lts/Plugins/AdvancedSymbology/` (37 files): `Data/asb_data_plugin.*`,
`Data/asb_foreign_interface_impl.*`, `Data/logger.*`, `Gui/SymbolEditor/*`,
`Gui/SymbolProxy/*`, `Helper/table_model_symbol_renderer*.*`, and the
`asb_*_interface.h` headers.
6. `Lts/Services/CentralEffectSimulation/Plugins/Explosions/expand_polygon.cpp`.
Do **not** touch `ElevationMap/` (removed) unless the task requires restoring it.
## Expected migration patterns (each must verify as migration-only)
These are the changes seen in the baseline audit. Each is an approved adaptation; when you
see one, confirm it is the exact legacy-equivalent transformation and leave it. If a file
deviates from the pattern (extra/missing logic), classify it as `semantic-change` and act.
- Qt include path churn: `#include <QX>` → `#include <QtCore/QX>` (and
`QtGui/`, `QtWidgets/`, `QtMultimedia/`, `QtNetwork/`, `QtSql/`, `QtXml/`,
`QtPrintSupport/`).
- `qAsConst(x)` → `std::as_const(x)` (Qt6 removed `qAsConst`).
- `QRegExp::exactMatch(s)` → `QRegularExpression::match(s).hasMatch()`; `QRegExp`
→ `QRegularExpression` (type + include).
- `QString::count()` → `QString::size()` (`count()` removed in Qt6).
- `QString::leftRef(n)` → `QString::left(n)` (`leftRef` removed in Qt6; a `// Qt6:
leftRef removed` note may accompany it).
- `QString::split(...)`: in Qt6 the `QStringView` overload is gone and `split()` returns
`QStringList`. Sites may now use `QVector<QStringView>` or `QStringList` — verify the
chosen type is behavior-identical (same element order/values, same `last()`/indexing).
- New `const QStringView &` overloads added to the SIDC codec helpers
(`decodeSymbology`, `decodeSidc`, `encodeBaseSymbolCode`, `encodeComplete`,
`encodeCivilEts`, `encodeCivilXml`) that delegate to the `QString` overloads
(`.toString()`). Verify the delegate body is an exact pass-through.
- ArcGIS include path: old `<arcgis/X.h>` → the SDK-300 layout. Reconcile to ONE consistent
form (see procedure step 6) that matches how the CMake sets the SDK include path.
- `const QImage &img = x.image()` → `const QImage img = x.image()` (Qt6 `QImage::image()`
returns by value).
## Verify carefully (potential behavior changes — do NOT auto-accept)
These are the non-obvious changes. For each, prove the legacy semantics are preserved in
the validated (ON) build, or report a blocker. Files are given so you do not hunt.
1. **`ParticipantManagement::Role_def::*` → `Role::*`** — file
`Lts/Viewer/SituationMap/Symbology/symbol_data_to_render_role.h`. Legacy references the
DDS-generated enumerator set `Role_def`; migrated references `Role`. This is a
DDS-generated-type rename. **VERIFY the enum value mapping is 1:1** — every
`Role_def::X` → `Role::X` with the same numeric value/meaning (`Unknown`, `Friend`,
`Neutral`, `Enemy`, `Pending`, `AssumedFriend`, `Suspect`, …). If the generated `Role`
enum dropped, added, or reordered any enumerator, flag it (the value→role mapping must be
preserved).
2. **`#ifdef BUILD_WITH_EXTERNAL_DDS` role-conversion stub** — files
`Lts/Viewer/SituationMap/Symbology/symbol_data_to_render_role.h` and
`Lts/Plugins/AdvancedSymbology/Data/asb_foreign_interface_impl.{h,cpp}`. When external
DDS types are absent, `roleToRole(...)` returns `Role::Unknown` (a STUB) instead of the
real conversion. This is a runtime behavior change vs legacy. **Confirm:**
(a) the real path (external-DDS available) still matches legacy 1:1; (b) the STUB path is
never the one exercised in the validated ON build; (c) the stub is documented as
intentional migration scaffolding. Do NOT "fix" the stub to look real, and do NOT let it
leak into the validated build.
3. **Logger pattern** — files `Lts/Viewer/SituationMap/SymbologyImpl/
advanced_symbology_logging.{h,cpp}`, `symbol_dictionary_impl.cpp`,
`esri_dictionary_processor.cpp`, `base_symbol_model.cpp`. Legacy
`LOGGER_T m_logger = getLogger("...")` (local) → migrated **member**
`NGL::INGLLogger &m_logger` initialized in the constructor (`, m_logger(getLogger(...))`).
Matches the known export-header/logger migration pattern. **VERIFY** there is no
double-allocation, lifetime, or initialization-order issue, and the logger name string is
unchanged.
4. **QAbstractItemModel filter API** — file
`Lts/Viewer/SituationMap/SymbologyImpl/base_symbol_model.cpp`. Legacy
`invalidateFilter()` → migrated `beginFilterChange()` / `endFilterChange()` (Qt6 removed
`invalidateFilter()`). **VERIFY** every `invalidateFilter()` call is correctly wrapped
(a `beginFilterChange()` before the change and an `endFilterChange()` after), preserving
the same filtering semantics.
## Mandatory build variants
Only these variants are valid for validation:
- `BUILD_RTI=ON`
- `BUILD_GRANTLEE=ON`
- `BUILD_ARCGIS=ON`
Forbidden: `BUILD_RTI=OFF`, `BUILD_GRANTLEE=OFF`. Do not implement, fix, preserve, test, or
validate OFF variants of `BUILD_RTI`/`BUILD_GRANTLEE` (no CMake logic, tests, stubs, or
fallbacks for them). `BUILD_ARCGIS` must be **ON** for this task (the ArcGIS map layer is
the point). The `#ifdef BUILD_ARCGIS` / `#ifdef BUILD_WITH_EXTERNAL_DDS` guards and their
STUB fallbacks are accepted migration scaffolding, but the validated build must use the
real, legacy-faithful (ON) path.
## Preservation rules
- Migration-only: every change must be justified against the legacy Qt5 source at the same
relative path. No behavior change in the ON-variant / validated build.
- No refactoring, no style cleanup, no warning suppression, no new features, no
opportunistic modernization.
- Do not restore removed modules or the `ElevationMap/` directory unless this task
explicitly requires it.
- Never commit generated outputs. No fake/dummy/stub files beyond the accepted
`BUILD_ARCGIS`/`BUILD_WITH_EXTERNAL_DDS` scaffolding that already exists.
- Any required existing stub/forward declaration must live only under
`qt6-after/qt6-migrated-legatus/forward-declarations/` or
`qt6-after/qt6-migrated-legatus/.forward-declarations/include/`; do not leave such files
in service/plugin directories.
- Keep the `Esri::ArcGISRuntime::*` type names (do not "modernize" them away).
- Keep the SIDC symbology pure-Qt: do not introduce arcgis includes into `Symbology/`,
`SymbologyImpl/`, or `SymbologyXML/` (they have none today).
## Legacy comparison (required validation step)
This step proves the migration did not change code behavior.
Reference audit command (reproduce; CRLF-ignored, only files present in both trees):
```bash
cd ./qt-migration-legatus
LEG=qt5-before/qt5-legatus-legacy/Lts/Viewer/SituationMap
MIG=qt6-after/qt6-migrated-legatus/Lts/Viewer/SituationMap
: > /tmp/sym_cr.diff; n_real=0
while IFS= read -r rel; do
if [[ -f "$LEG/$rel" && -f "$MIG/$rel" ]] && ! diff -q "$LEG/$rel" "$MIG/$rel" >/dev/null 2>&1; then
if diff -q --strip-trailing-cr "$LEG/$rel" "$MIG/$rel" >/dev/null 2>&1; then :; else
n_real=$((n_real+1)); diff -u --strip-trailing-cr "$LEG/$rel" "$MIG/$rel" >> /tmp/sym_cr.diff
fi
fi
done < <(cd "$LEG" && find . -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) | sed 's#^\./##' | sort)
echo "files with real changes: $n_real"
```
For every file you edit (and, as a sweep, every in-scope file):
1. Read the legacy Qt5 source at the same relative path in
`./qt-migration-legatus/qt5-before/qt5-legatus-legacy`. If the file does not exist there
(e.g. a pure-Qt6 scaffolding header), say so and compare against the pre-migration
baseline.
2. Produce the audit diff: migrated result vs legacy (CRLF-ignored).
3. Classify every hunk of the audit diff into exactly one category:
- `qt6-api`: mandatory Qt5→Qt6 API adaptation (the pattern list above)
- `sdk300-api`: mandatory ArcGIS old-SDK → Maps-SDK-300 adaptation
- `build`: CMake/docker/test-infra change with no runtime semantics
- `stub-scaffolding`: an accepted `#ifdef BUILD_ARCGIS` / `BUILD_WITH_EXTERNAL_DDS`
guard (documented, OFF-path only)
- `semantic-change`: anything else
4. Every `semantic-change` hunk is a failure of this task unless you can point to the legacy
source line that implements the same behavior. Fix it back to the legacy semantics (with
approved adaptations) or report it as a blocker. Do not silently accept `semantic-change`
hunks.
5. Record the per-file hunk classification (counts per category is sufficient; list every
`semantic-change` hunk explicitly) in the final report.
## Docker and CI
- Authoritative validation script:
`./qt-migration-legatus/qt6-after/qt6-migrated-legatus/new_docker_build.sh`
- Prebuilt image `legatus-qt6-prebuilt:latest` (has local PostgreSQL; the DB is
auto-provisioned by the `ensure_database` step — no office DB needed).
- ArcGIS SDK under `/workspace/external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/
qt300.0.0/sdk` (mounted from the pipeline root `external/`); repo root at `/workspace`.
- `new_docker_build.sh` is the single validation script; do not reintroduce a second script.
## Required procedure
1. Read the base prompts. `git fetch origin`; confirm the working branch and the working-
tree state (protect the two uncommitted files from "Branches and trees").
2. Confirm the ArcGIS SDK 300.0.0 directory exists at the pipeline-root `external/` path
(and therefore `/workspace/external/...` in the container).
3. Re-run the audit command over `SituationMap/` and `Lts/Plugins/AdvancedSymbology/`
(CRLF-ignored); confirm the baseline (SituationMap ~96 files, AdvancedSymbology 37 files,
all migration-only). Record any drift.
4. For each in-scope file, diff vs legacy and classify every hunk (see "Legacy comparison").
Fix any `semantic-change` back to legacy semantics (with approved adaptations) or report
a blocker.
5. Resolve the four "Verify carefully" items (Role value mapping; the DDS roleToRole stub
real-path vs legacy; the logger pattern; the filter API pairing).
6. Reconcile the ArcGIS include style (the `arcgis/` prefix question) across the 11 migrated
arcgis includes to ONE consistent form that matches the SDK 300 include path set in CMake.
Record which form you chose and why.
7. Confirm the Esri dictionary processors still parse the same `.style` / MIL-STD-2525D /
App-6 / App-6D dictionaries as legacy (same `Esri::ArcGISRuntime::*` types, same symbol
results; only includes changed).
8. Build the symbology targets with `BUILD_RTI=ON BUILD_GRANTLEE=ON BUILD_ARCGIS=ON` (the
Viewer/SituationMap targets + the AdvancedSymbology plugin targets + `expand_polygon`)
and confirm they compile **and link** against the 300.0.0 SDK.
9. Run the relevant CTest tests.
10. Create the commit(s) (see "Commits").
11. Report factual status and write the summary (see "Summary").
Do not push. The result stays local on the working branch until the user says otherwise.
## Required validation
Targeted (fast, focused) — from the repo root, in the validation container (repo at
`/workspace`):
```bash
cmake -S /workspace/qt-migration-legatus/qt6-after/qt6-migrated-legatus \
-B /workspace/build-arcgis300-symbology -G Ninja -DCMAKE_BUILD_TYPE=Debug \
-DBUILD_RTI=ON -DBUILD_GRANTLEE=ON -DBUILD_ARCGIS=ON \
-DUSE_IPO=ON -DUSE_UNITY_BUILD=ON -DGUEZ_MODE=ON -DBUILD_WLS=ON \
-DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql/
# Discover the exact SituationMap + AdvancedSymbology target names from the
# SituationMap/AdvancedSymbology CMakeLists (or new_docker_build.sh's GROUP5_TARGETS),
# then build only those (faster than the whole tree):
cmake --build /workspace/build-arcgis300-symbology --target <situationmap_target> \
<asb_symbol_editor> <asb_symbol_proxy> <asb_data_plugin> --parallel
ctest --test-dir /workspace/build-arcgis300-symbology --output-on-failure
```
End-to-end via the validation script (the Viewer group carries the SituationMap targets;
also build the group that owns the AdvancedSymbology plugin targets — identify it from
`GROUPn_TARGETS` in `new_docker_build.sh`):
```bash
cd ./qt-migration-legatus/qt6-after/qt6-migrated-legatus
BUILD_RTI=ON BUILD_GRANTLEE=ON BUILD_ARCGIS=ON ./new_docker_build.sh \
--use-prebuilt-image --docker-image legatus-qt6-prebuilt:latest --group5
```
Mandatory positive checks:
- The SituationMap map layer compiles and links against the ArcGIS Maps SDK 300.0.0 targets
(no undefined `Esri::ArcGISRuntime::*` refs; no Qt5 imported-target links).
- The Esri dictionary-symbol processors build and the SIDC codec/dictionary tests pass
(same symbol results as legacy for the same inputs).
- The AdvancedSymbology plugin targets build.
- No `***Failed`/`***Timeout` CTest entries beyond documented base-state failures
(record any base-state failures as base state, do not weaken a test to make it pass).
- No active Qt5 imported-target links (`Qt5::`, `find_package(Qt5`, `Qt5Core`, …) in the
touched targets.
Do not run or validate OFF variants of `BUILD_RTI`/`BUILD_GRANTLEE`.
## Commits
Commits on the working branch:
- Single author — the user's git identity (berrux-dev <berrux.kana@axilinx.com>). The user is
the only author; do NOT add any co-author, co-authored-by, or bot attribution lines of any
kind.
- Message: maximum 2 lines (one subject line plus at most one short body line), no blank-line
separators, no extra metadata. Subject example:
`Qt6: verify/complete ArcGIS 300 symbology migration (SituationMap + AdvancedSymbology)`
- The repository has `commit.gpgsign=false`: sign every created commit explicitly
(`git commit -S`). Follow `./prompts/commit-policy.prompt.md` for repository mapping and
pre-commit checks. If signing is not configured in this repository context, stop and
report the exact reason instead of committing unsigned.
- Keep the two unrelated uncommitted files (`new_docker_build.sh` DB step,
`tests/CMakeLists.txt` guard fixes) OUT of the symbology commit unless the user says
otherwise.
- If a fix requires an additional commit, the same 2-line / single-author / no-attribution /
signed rules apply.
## Success criteria
Success requires:
- every in-scope file diffed vs legacy and every hunk classified; zero unexplained
`semantic-change` hunks (each one either fixed to legacy semantics or reported as a blocker)
- the four "Verify carefully" items resolved with evidence (Role 1:1 mapping; the DDS
roleToRole stub real-path matches legacy and does not leak into the ON build; the logger
pattern is sound; the filter API pairing is correct)
- the 11 migrated arcgis includes reconciled to ONE consistent include style (recorded)
- the Esri dictionary processors confirmed to parse the same dictionaries as legacy
- configure, build (link), and CTest pass with `BUILD_RTI=ON BUILD_GRANTLEE=ON
BUILD_ARCGIS=ON` for the symbology targets
- no active Qt5 imported-target links in the touched targets; generated outputs build-tree
only, never committed; no fake/dummy/stub files beyond the accepted scaffolding
- required stubs/forward declarations only in allowed directories
- no OFF-variant logic/stubs for `BUILD_RTI`/`BUILD_GRANTLEE` introduced
- the commits are signed (verify Good), single-author, ≤2-line, no bot attribution
- no push performed
## If blocked
Do not fake success. Report:
- failing command and key error output
- affected file/branch
- category: project, path, CMake, Qt API, ArcGIS-SDK-300, DDS-generated-types, codegen,
Docker, RTI/license, test, CTest, stub scaffolding, or environment
- the specific in-scope file and hunk, and which category it was misclassified as
- what was resolved safely, what remains blocked
- whether stale artifacts were ruled out
- whether generated files or the ArcGIS SDK path were involved
- the legacy comparison status for the unresolved files
## Final report
Keep it short. Include:
- status: validated, partially validated, or blocked
- the working branch name and the commit hash(es) (signed)
- the re-run audit baseline (SituationMap / AdvancedSymbology file + changed-line counts) and
any drift vs the 2026-10-06 baseline
- per-scope-area hunk counts by category, and every `semantic-change` hunk with its
justification or fix
- the four "Verify carefully" resolutions with evidence (Role mapping; DDS stub real-path;
logger; filter API)
- the ArcGIS include-style decision (prefix vs bare) and the reason
- the Esri dictionary-processor equivalence evidence
- exact validation commands and results (targeted build + the `--group5` docker run + ctest)
- remaining blockers or risks
## Summary
Write a `MIGRATION_SUMMARY_ARCGIS300_SYMBOLOGY.md` (same style/convention as
`MIGRATION_SUMMARY_Z_AND_PROXIES.md`) documenting: the scope audited, the migration-only
pattern classes found, the four verify-carefully resolutions, the ArcGIS 300 include-style
reconciliation, the validation commands/results, and the remaining blockers. Place it at the
migrated-tree root (`qt6-after/qt6-migrated-legatus/`) and commit it with the work.