Skip to content

fix: merge unstable into dev for PR 490 promotion readiness - #514

Merged
cursor[bot] merged 22 commits into
devfrom
cursor/pr-490-promotion-fix-23e1
Sep 2, 2026
Merged

fix: merge unstable into dev for PR 490 promotion readiness#514
cursor[bot] merged 22 commits into
devfrom
cursor/pr-490-promotion-fix-23e1

Conversation

@mberrys

@mberrys mberrys commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves merge conflicts blocking PR 490 (devunstable) and fixes the failing source_integrity / policy gates on dev.

Changes

  • Merged origin/unstable into dev workstream, resolving legacy-to-Loop rename conflicts across policy adapters, docs, workflows, packaging, and CMake.
  • Regenerated docs/generated/phase5-widgets-inventory.json (70 targets; stale counts.targets was 68 while the array held 69).
  • Renamed interaction/resource envelope schema kinds and corpus digests from legacy loupe-* to loop-* so check_loop_identity.py passes.
  • Updated dev-added Quick/document search files to Loop naming (Loop.Quick, LOOPLIBCORESHARED_EXPORT).
  • Preserved dev promotion policy (agent-fast gate on unstable) and Session 07 packaging improvements (QML staging, windeployqt, linuxdeployqt evidence).

Verification

  • python3 -m unittest discover -s scripts/ci -p 'test_*.py' — 223 tests OK (1 skipped)
  • python3 scripts/ci/check_source_integrity.py — passed
  • python3 scripts/generate_phase5_widgets_evidence.py --check — passed
  • python3 scripts/ci/check_loop_identity.py — passed
  • git merge-tree against origin/unstable — no conflict markers predicted
  • CI on this PR: source_integrity ✅, policy

Files resolved (conflicts)

.claude/policy-brief.md, .cursor/agent-policy.md, AGENTS.md, .github/workflows/LinuxInstall.yml, .github/workflows/WindowsInstall.yml, UnitTests/phase4-tests.cmake, WixInstaller/Product.wxs.in, docs/0.2.0-closeout-matrix.md, docs/CI.md, docs/JOB_SCHEDULER.md, docs/LOOP_SHELL_CONTRACT.md, docs/LOOP_WORKSPACES.md, docs/PLATFORM_SUPPORT.md, docs/REPO_MAP.md, docs/SEMANTIC_TRUST_ENGINE_ACCEPTANCE.md, docs/generated/phase5-widgets-inventory.json, scripts/agent/generate-adapters.py, scripts/ci/check_phase5_residue.py, plus file-location conflicts for LoopEditor/qml/DocumentPane.qml, LoopEditor/quickdocumentmodel.{cpp,h}, and LoopLibCore/sources/pdfdocumentsearch.{cpp,h}.

Next step: merge this PR into dev to unblock PR 490.

Open in Web Open in Cursor 

mberrys and others added 22 commits August 31, 2026 12:18
…356)

Summary

0.2.0 completes Loupe’s architectural migration from the Qt
Widgets-owned interactive product to a Qt Quick Controls 2 application
shell with a direct QQuickItem PDF canvas.

This release moves presentation and interaction onto the new Quick
architecture while preserving the existing PDF, rendering, preflight,
scheduling, revision, and mutation authority in C++. Qt Widgets remains
only where explicitly retained for non-product or developer
compatibility; it is no longer part of the supported interactive product
architecture.

0.2.0 also absorbs the unfinished 0.1.1 qualification work. There is no
separate 0.1.1 release.

Major changes

* Migrated the supported application shell to Qt Quick Controls 2.
* Introduced the direct QQuickItem scene-graph PDF canvas.
* Established host-neutral interaction and rendering boundaries between
Core and presentation.
* Added revision- and generation-fenced render admission to prevent
stale presentation results.
* Preserved the existing CPU/color-managed renderer behind bounded
asynchronous render requests.
* Migrated workspace, command, inspector, preflight, finding, and
navigation surfaces to the Quick product architecture.
* Preserved semantic operation boundaries for selection, pointer, pan,
zoom, drag, and document mutation.
* Added explicit scene-graph lifecycle, cancellation, device-loss,
cache-pressure, and recovery handling.
* Preserved software-rendering support as a first-class product path.
* Tightened QML authority boundaries: document mutation,
filesystem/network/process access, scheduler ownership, and raw customer
payloads remain outside QML.
* Consolidated command and interaction behavior around typed C++
facades/models rather than exposing Core objects directly to QML.
* Removed Qt6::Widgets and LoupeLibWidgets dependencies from supported
interactive product targets.
* Classified remaining Widgets surfaces as migrated, retired, or
explicitly retained non-product compatibility surfaces.
* Superseded stale hybrid/Widgets-fallback architecture language with
the binding Quick-only architecture.
* Carried the deferred 0.1.1 trust-contract, independent-validation,
resource-envelope, and lifecycle-model qualification into the 0.2.0
release gate.

Architecture

The supported product dependency direction is now:

QML / Qt Quick → typed C++ facade → interaction layer → Core / scheduler
/ renderer

QML owns presentation. C++ continues to own document identity,
mutations, rendering truth, persistence, scheduling, policy, and
long-lived state.

The Quick canvas consumes immutable presentation snapshots and rejects
results whose document revision, page, render configuration, DPI,
zoom/tile identity, or request generation no longer match the active
view.

No parallel renderer, scheduler, revision system, command registry, or
document-mutation path is introduced.

Validation

0.2.0 qualification covers:

* architecture and dependency checks
* revision/stale-result fencing
* scheduler and cancellation behavior
* render/cache pressure and recovery
* scene-graph lifecycle and device loss
* interaction and command parity
* focus, keyboard, and accessibility behavior
* renderer/color/fidelity differential testing
* software rendering
* packaging and clean-machine launch
* Linux and Windows qualification
* inherited trust-contract and independent-validation evidence
* production-scale resource-envelope testing
* deterministic lifecycle generation, replay, shrinking, and regression
coverage

Release qualification must be performed against the exact candidate SHA.
A hard Quick architecture or parity failure blocks or extends 0.2.0; it
does not silently restore Widgets as the product host.

Release impact

This is the primary UI architecture transition for Loupe before
subsequent 0.3.0 governed-correction and 0.4.0 agent-focused work.

Version: 0.2.0
Merge the Loupe-to-Loop rename onto current dev while keeping Phase 5
Widgets deletions. Restore pdftoolenvelopeutils and preflightsidecarutils
headers for UnitTestsOperatorAcceptance after the plugin pack removal.

Resolves merge conflicts between #383 and dev for the 0.2.0 stack.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
After rebasing onto dev (#386), Release Gate failed because Session 05
closeout scripts still referenced Loupe targets, loupe-release profile,
and docs/loupe-shell.json. Update evidence generators, verifiers, and
CI regression tests to use Loop naming and regenerate JSON artifacts.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
UnitTestsPageSurfaceBudget and UnitTestsDocumentViewSession still linked
LoupeLibInteraction, LoupeLibCore, and LoupeEditorQuick after the product
rename, so Release Gate linux/windows builds could not resolve
pagesurfacecoordinator.h and documentviewsession.h.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Linux Release Gate configures with LOOP_LOOP_DISTRIBUTION=ON, which installs
only the consolidated desktop entry. The verify step was still checking the
developer profile and would fail on the missing LoopEditor.desktop file.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
The bundled profile id and name changed from loupe-default/Loupe Default
to loop-default/Loop Default but kept the old digest, causing
profile-digest-mismatch failures in UnitTestsProfileIdentity,
UnitTestsPreflightCorpus, and operator acceptance tests on Release Gate.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Use QGuiApplication::setApplicationDisplayName only when the running
instance is a QGuiApplication so core-only builds (fuzz, PdfTool) compile.
Pass VCPKG_INSTALLED_DIR to Widgets-absent configure probes so temp
build directories reuse the preinstalled vcpkg tree.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
- Restore CMake product identity defines and project(LOOP)
- Fix remaining LOUPE tokens in WiX, Windows CI, smoke scripts, and docs
- Regenerate architecture and phase5-widgets evidence catalogs
- Align loop-release profile naming in contract scripts

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Link LoopLibCore from QuickShellSmoke and CanvasBenchmark so
initializeApplicationIdentity() resolves during Widgets-free CI builds.

Extract _truncate_command_output() for the release-profile verifier so
the regression test matches the configure diagnostic truncation behavior.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
QCoreApplication has no applicationDisplayName(); the display name is
set via initializeApplicationIdentity on QGuiApplication.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Widgets-free CI runs QuickShellSmoke from the build tree without install.
LoopLibCore.dll lives under usr/bin/Release while the smoke exe defaulted to
build/Release, so Windows failed with STATUS_DLL_NOT_FOUND (0xC0000135).
Align output directories with ProductQuickAccessibilitySmoke.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Rebase conflict resolution pulled stable sources with incomplete Loupe→Loop
renames in headers, product-surface scripts, and CMake. Restore the Loop
identity contract across the affected files.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
After setSettingsPath redirects UserScope IniFormat settings into a temp
directory, corruptLegacySettingsDoNotBlockStartup must create the parent
path before writing a broken legacy file.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
## Summary

Completes the **Loupe → Loop** product rename across the repository and
establishes `Loop` as the canonical product, build, package, and runtime
identity.

This goes beyond UI/string replacement: it updates source/module names,
CMake targets and configuration, CI/release infrastructure, packaging
identifiers, application identity, settings, scripts, documentation, and
agent/development tooling so the repository no longer depends on the
previous Loupe naming.

## What changed

- Renamed core project/module identities:
  - `LoupeLibCore` → `LoopLibCore`
  - `LoupeLibInteraction` → `LoopLibInteraction`
  - `LoupeEditorPlugins` → `LoopEditorPlugins`
- associated CMake targets, export macros, include paths, generated
headers, and references
- Renamed build configuration from `LOUPE_*` to `LOOP_*`, including
version, install, feature, build, and environment variables.
- Added canonical product identity configuration:
  - product: `Loop`
  - organization: `Loop`
  - package ID: `io.github.mberrys.Loop-pdf`
- Updated application/runtime identities to consistently use Loop rather
than legacy Loupe/MelkaJ identifiers.
- Added centralized application identity initialization for the
different executable surfaces.
- Added one-time migration of legacy `QSettings` data so existing user
preferences can move to the new Loop identity rather than being silently
lost.
- Updated Linux/Windows packaging and release infrastructure, including:
  - Flatpak IDs and manifests
  - release artifact names
  - package-boundary evidence artifacts
  - release version variables
  - repository/workspace paths
- Updated CI workflows, fuzzing configuration, scripts, tests, generated
architecture/policy artifacts, developer environment configuration, and
repository guards.
- Updated documentation and developer/agent policy references from Loupe
to Loop.
- Updated repository references from `studio-berry/loupe` to
`studio-berry/loop`.

## Compatibility / review notes

This PR intentionally changes developer- and package-facing identifiers
as part of completing the rename. The large diff is primarily caused by
repository-wide path, target, macro, and identity changes rather than a
similarly large expansion in product functionality.

The settings migration is specifically intended to preserve existing
configuration where possible across the application identity change.

Reviewers should use rename-aware diff views where possible; raw
line-count statistics substantially overstate the amount of logically
new code.

## Validation

The rename is covered by the existing repository policy/validation
infrastructure, including checks around canonical product identity,
version configuration, application identity, packaging, documentation
consistency, and CI references.

Current CI has already passed:

- Documentation truth
- Supply Chain Policy
- CodeQL Advanced

Fuzz and Release Gate validation are also running against the renamed
tree.
Resolve Loop/Loupe rename conflicts from the 0.2.1 promotion branch,
regenerate Phase 5 widgets inventory (70 targets), refresh interaction-trace
manifest digests after schema_kind renames, and align policy/workflow
contracts with Loop naming.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
@mberrys
mberrys marked this pull request as ready for review September 2, 2026 03:35
@cursor
cursor Bot merged commit 0cf1acf into dev Sep 2, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants