From 253aed48f661b5009c95d2a298cb7038081ac1f8 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:08:56 +0530 Subject: [PATCH 01/48] ci(sync): align focused workflow action majors --- .github/workflows/project-sync-safety.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/project-sync-safety.yml b/.github/workflows/project-sync-safety.yml index 9362a5f..d7cd6cb 100644 --- a/.github/workflows/project-sync-safety.yml +++ b/.github/workflows/project-sync-safety.yml @@ -41,10 +41,10 @@ jobs: steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v7 with: python-version: "3.12" cache: pip From 4eda83909a62fb2fd6dbf6a3ca05da6e50b681a8 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:09:13 +0530 Subject: [PATCH 02/48] chore(version): prepare package metadata for 2.8.5 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 263c34d..2546b23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "docmergeforge" -version = "0.1.0" +version = "2.8.5" description = "Local-first, validation-driven PDF and DOCX merger for large multi-part publications." readme = "README.md" requires-python = ">=3.12" From 1823ff8bf406055298dbdaed82f84a83d836196a Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:09:25 +0530 Subject: [PATCH 03/48] chore(version): expose 2.8.5 package version --- src/docmergeforge/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docmergeforge/__init__.py b/src/docmergeforge/__init__.py index 48f7c91..c986183 100644 --- a/src/docmergeforge/__init__.py +++ b/src/docmergeforge/__init__.py @@ -1,3 +1,3 @@ """DocMergeForge package.""" -__version__ = "0.1.0" +__version__ = "2.8.5" From 67015d621ca4b86ab4731b79dded7e0badd967e8 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:09:38 +0530 Subject: [PATCH 04/48] test(version): pin 2.8.5 release candidate metadata --- tests/unit/test_version_metadata.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/unit/test_version_metadata.py b/tests/unit/test_version_metadata.py index f52d97f..29b7c00 100644 --- a/tests/unit/test_version_metadata.py +++ b/tests/unit/test_version_metadata.py @@ -3,6 +3,8 @@ from docmergeforge import __version__ +EXPECTED_RELEASE_VERSION = "2.8.5" + def _pyproject() -> dict[str, object]: root = Path(__file__).resolve().parents[2] @@ -16,6 +18,14 @@ def test_pyproject_version_matches_package_version() -> None: assert project["version"] == __version__ +def test_release_version_is_pinned_for_candidate() -> None: + pyproject = _pyproject() + project = pyproject["project"] + assert isinstance(project, dict) + assert project["version"] == EXPECTED_RELEASE_VERSION + assert __version__ == EXPECTED_RELEASE_VERSION + + def test_public_console_scripts_use_maintained_entry_points() -> None: pyproject = _pyproject() project = pyproject["project"] From 1ee0e76d6714cd4c2c15c02dc6c8edaeab918454 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:10:45 +0530 Subject: [PATCH 05/48] docs(state): advance checkpoint to 2.8.5 preparation --- PROJECT_STATE.md | 140 ++++++++++++++++++++++++++++++----------------- 1 file changed, 91 insertions(+), 49 deletions(-) diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 60a82a7..162d757 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -5,25 +5,59 @@ This file is the compact continuation checkpoint for future development sessions ## Current checkpoint - Repository: `sanskarIN/DocMergeForge` -- Branch: `main` -- Version declared in `pyproject.toml`: `0.1.0` -- Checkpoint immediately before this state-file commit: `b2379226f7681ffe64a2dcfa3b9d59c75006bf30` -- Continuation base for the latest completed feature: `9775190f38e613e33f20aafc82b678a1ca3a233d` -- Development status: pre-stable; do not claim `v1.0.0`, production certification, native mobile packaging, or completed signing/notarization from source changes alone. +- Target branch: `main` +- Active release-preparation branch: `release/2.8.5-prep` +- Version declared in `pyproject.toml`: `2.8.5` +- Release-preparation base: `aac5bf6d275991e21b68e15f5ad31f084fbc72e2` +- Development/release status: `2.8.5` candidate preparation; package versioning does **not** by itself certify production readiness, native mobile packaging, signing/notarization, human accessibility acceptance, or external-office fidelity. -## Latest completed continuation: guarded desktop project synchronization +## Latest continuation: 2.8.5 release preparation -The desktop application now exposes the existing review-first project synchronization model that was previously available through the CLI. +The `2.8.5` preparation pass is intentionally evidence-first. It updates package/runtime version metadata and release-facing documentation without converting unobserved CI, packaging, device, accessibility, stress, signing, or fidelity gates into passing claims. + +### Release metadata + +The candidate version is synchronized across: + +- `pyproject.toml` — package version `2.8.5`; +- `src/docmergeforge/__init__.py` — runtime `__version__ = "2.8.5"`; +- `tests/unit/test_version_metadata.py` — package/runtime synchronization plus an explicit `2.8.5` candidate pin. + +The existing pre-alpha distribution classifier remains intentionally conservative. A numeric version change is not used as a substitute for release acceptance evidence. + +### Workflow-generation cleanup + +The focused Project Sync Safety workflow was the remaining workflow still using older GitHub Action majors. The release-preparation branch aligns it with the repository's maintained Node-24-era action generations: + +- `actions/checkout@v7`; +- `actions/setup-python@v7`. + +This incorporates the substantive changes proposed independently by Dependabot PRs #3 and #4 into one reviewed release-preparation line. The PRs should be closed as superseded after the release branch is merged, not represented as separately required product work. + +### Recent-project synchronization status corrected + +The desktop convenience shortcut from **Recent Projects** into the guarded synchronization workflow is already implemented on current `main` and covered by integration tests. It is no longer future work. + +`ProjectSyncMainWindow` exposes both: + +- **Synchronize Project Sources** — browse for a project JSON; +- **Synchronize Recent Project** — select from maintained recent-project history. + +Both routes converge on the same `_synchronize_project_path(...)` guarded workflow and therefore preserve the same preview, duplicate blocking, separate removal approval, exact-revision propagation, backup, stale-write, and metadata-only semantics. + +## Previous completed continuation: guarded desktop project synchronization + +The desktop application exposes the existing review-first project synchronization model that was previously available through the CLI. ### Maintained public desktop entry -`pyproject.toml` now routes: +`pyproject.toml` routes: ```text docmergeforge-gui = "docmergeforge.ui.desktop_entry:main" ``` -`src/docmergeforge/ui/desktop_entry.py` provides `ProjectSyncMainWindow`, an extension of the established desktop `MainWindow` that adds **Synchronize Project Sources** without duplicating project discovery/synchronization business logic. +`src/docmergeforge/ui/desktop_entry.py` provides `ProjectSyncMainWindow`, an extension of the established desktop `MainWindow` that adds synchronization actions without duplicating project discovery/synchronization business logic. Normal installed desktop startup and normal packaged desktop startup both route through this synchronization-enabled entry. @@ -31,7 +65,7 @@ Normal installed desktop startup and normal packaged desktop startup both route The maintained desktop flow is: -1. select a saved project JSON; +1. select a saved project JSON directly or through recent-project history; 2. load the project and exact SHA-256 content revision from the same byte snapshot; 3. call the shared `plan_project_sync(...)` planner; 4. show a read-only preview containing current/proposed counts, additions, removals, reordering, duplicate parts, missing parts, and complete proposed order; @@ -64,35 +98,42 @@ Desktop and CLI synchronization intentionally share these rules: The SHA-256 project revision mechanism is still an **optimistic stale-write guard**, not a universal cooperative cross-process lock. Do not represent simultaneous multi-writer editing as solved unless a separate coordinated locking/revision protocol is designed and accepted. -## New/changed runtime paths in the latest continuation +## Runtime and documentation paths associated with desktop synchronization -### Added +### Added in the desktop-sync continuation - `src/docmergeforge/ui/desktop_entry.py` — synchronization-enabled maintained desktop startup and workflow orchestration. - `src/docmergeforge/ui/project_sync_dialog.py` — accessible synchronization review dialog. -- `tests/integration/test_project_sync_desktop.py` — offscreen Qt/workflow regression coverage for the new desktop path. -- `docs/history/what_changed-through-2026-08-20-cross-platform.md` — verbatim archive of the previous top-level development record before this desktop-sync continuation. +- `tests/integration/test_project_sync_desktop.py` — offscreen Qt/workflow regression coverage for the desktop path, including browse and recent-project routing. +- `docs/history/what_changed-through-2026-08-20-cross-platform.md` — verbatim archive of the previous top-level development record before the desktop-sync continuation. -### Changed +### Changed across the synchronization/release-prep boundary -- `pyproject.toml` — public GUI console-script target. +- `pyproject.toml` — public GUI console-script target and `2.8.5` candidate package version. +- `src/docmergeforge/__init__.py` — `2.8.5` runtime package version. - `src/docmergeforge/ui/packaged_entry.py` — packaged startup/smoke uses the synchronization-enabled window. -- `src/docmergeforge/packaging/desktop.py` — packaging preflight requires the new desktop entry/dialog modules. +- `src/docmergeforge/packaging/desktop.py` — packaging preflight requires the desktop entry/dialog modules. +- `.github/workflows/project-sync-safety.yml` — focused safety matrix and maintained action majors. - `tests/unit/test_build_desktop.py` — packaging prerequisite coverage. -- `tests/unit/test_version_metadata.py` — pins maintained CLI/GUI/web public entry points. -- `README.md` — public desktop synchronization feature/safety description. +- `tests/unit/test_version_metadata.py` — pins maintained CLI/GUI/web public entry points and the `2.8.5` candidate version. +- `README.md` — public desktop synchronization feature/safety description and release-preparation status. - `docs/desktop-guide.md` — operator workflow. - `docs/project-sync.md` — shared desktop/CLI synchronization contract. - `docs/source-code-reference.md` — runtime responsibility map. - `docs/test-suite-reference.md` — test ownership/evidence map. -- `docs/repository-reference-cross-platform.md` — tracked-path coverage for the new files/archive. -- `what_changed.md` — current continuation record only; the preceding complete record is archived under `docs/history/`. +- `docs/repository-reference-cross-platform.md` — tracked-path coverage for the cross-platform/desktop additions. +- `docs/release-process.md` — versioning/release evidence policy. +- `docs/release-evidence.md` — evidence ledger; candidate evidence must use exact run/checkpoint IDs. +- `CHANGELOG.md` — release-preparation record. +- `what_changed.md` — active continuation record. ## Regression coverage added/expanded `tests/integration/test_project_sync_desktop.py` protects: -- presence/accessibility of the desktop synchronization action; +- presence/accessibility of both desktop synchronization actions; +- browse-project routing; +- recent-project routing; - accessible complete preview content; - disabled apply for ambiguous duplicate parts; - exact revision propagation into the shared apply path; @@ -104,8 +145,8 @@ The SHA-256 project revision mechanism is still an **optimistic stale-write guar Additional related coverage: - `tests/unit/test_build_desktop.py` requires the base window, desktop entry, sync dialog, and packaged entry in build-root preflight; -- `tests/unit/test_version_metadata.py` pins `docmergeforge`, `docmergeforge-gui`, and `docmergeforge-web` entry targets; -- `tests/integration/test_packaged_entry_smoke.py` now reaches the synchronization-enabled packaged window before the existing real temporary PDF/DOCX publication smoke. +- `tests/unit/test_version_metadata.py` pins `docmergeforge`, `docmergeforge-gui`, and `docmergeforge-web` entry targets and candidate version metadata; +- `tests/integration/test_packaged_entry_smoke.py` reaches the synchronization-enabled packaged window before the existing real temporary PDF/DOCX publication smoke. Committed test source is implementation evidence only until execution is observed. @@ -146,25 +187,15 @@ The tracked-file documentation checker reads the maintained reference corpus: - `docs/repository-reference.md`; - `docs/repository-reference-cross-platform.md`. -The latest continuation added exact backticked references for every new tracked runtime/test/history path before or alongside the corresponding file becoming part of the maintained checkpoint. - -The checker is configured in Quality and pre-commit. Configuration is not the same as an observed passing current-head execution. +The checker is configured in Quality and pre-commit. Configuration is not the same as an observed passing candidate-head execution. ## Verification boundary Do not infer a green build merely from commits being present. -During the latest continuation: - -- focused GitHub commit/tree/file inspection was used to keep changes scoped; -- packaging/source/test/documentation dependencies were cross-checked against the repository; -- an unintended temporary Ruff-rule-set expansion introduced while changing the GUI entry was immediately reverted in the next focused commit; -- the maintained Ruff rule set remains `E/F/I/B/UP/SIM/C4`; -- a raw GitHub archive/checkout could not be obtained in the execution environment, so local quality/test execution was not available; -- repository workflow definitions remain configured for Quality/Build Smoke, but no fresh passing current-head execution is claimed without observed run evidence. - -Until observed for the current head, no fresh pass is claimed for: +For the `2.8.5` candidate, no fresh pass is claimed until the exact release-preparation head is observed for the relevant gates. Required source evidence includes: +- pre-commit configuration validation; - Ruff; - Black check; - strict mypy; @@ -174,31 +205,42 @@ Until observed for the current head, no fresh pass is claimed for: - Quality workflow matrix; - 120-Part Regression; - Build Smoke; -- Package Desktop / Onefile Acceptance; -- Security/CodeQL; +- Project Sync Safety matrix; +- Security/CodeQL. + +Packaging/release evidence remains separate: + +- Package Desktop / Onefile Acceptance on Windows, macOS, and Linux; +- downloaded-artifact verification; - representative Android/iOS/iPadOS/ChromeOS/manual browser acceptance; -- human desktop accessibility/clean-machine acceptance. +- human desktop accessibility/clean-machine acceptance; +- external-office fidelity acceptance; +- measured stress at the workload class actually claimed; +- Windows signing; +- macOS signing/notarization; +- final distribution/installer acceptance where applicable. -External-office, measured stress, signing/notarization, and other release gates remain independent. +Older recorded passing runs remain historical evidence for their exact checkpoints and must not be relabeled as `2.8.5` candidate evidence. -## Repository administration state observed during this continuation +## Repository administration state -GitHub branch metadata reported `main` as not protected, with required status checks disabled at the repository-rules layer at the inspected checkpoint. +At the release-preparation base, GitHub branch metadata reported `main` as not protected, with required status checks disabled at the repository-rules layer. This is an administrative governance state, not an application correctness failure. If enforced review/CI policy on `main` is desired, configure branch protection/rulesets through repository administration with the intended required checks. Do not claim protection is enabled until repository metadata confirms it. ## Recommended next development work -1. Observe a current-head Quality run; fix any lint/format/type/test/link/reference failure without weakening maintained rules. -2. Review current Build Smoke and packaged-app results specifically for the synchronization-enabled desktop entry on Windows, macOS, and Linux. -3. If a convenience shortcut from **Recent Projects** into synchronization is added, preserve the same preview, duplicate blocking, separate removal approval, exact revision, and backup semantics; do not bypass them. -4. Keep synchronization domain rules centralized in `project.sync` rather than forking CLI and desktop business logic. +1. Open/review the `release/2.8.5-prep` pull request and observe Quality plus the focused Project Sync Safety checks for the exact candidate head. +2. Fix any Ruff/Black/mypy/docs/reference/pytest/CI failure without weakening maintained checks. +3. Review current 120-Part Regression, Build Smoke, Security/CodeQL, Package Desktop, and Onefile Acceptance evidence for the exact candidate commit. +4. Keep synchronization domain rules centralized in `project.sync`; both browse and recent-project desktop actions must continue to converge on the shared guarded workflow. 5. Perform representative manual browser/device acceptance for the responsive cross-platform client. 6. If Internet/untrusted-network hosting is intentionally supported later, define and acceptance-test an explicit HTTPS reverse-proxy/authentication/body-limit/timeout/concurrency/host-hardening deployment profile. 7. If simultaneous multi-writer project editing becomes a supported requirement, design a separate coordinated lock/revision protocol rather than relabeling the optimistic revision guard. 8. Continue independent release-gate work for native-office fidelity, measured multi-gigabyte stress, human accessibility, clean-machine packaged applications, Windows signing, and macOS signing/notarization. -9. Keep README, project-sync/desktop/source/test references, repository-reference corpus, `what_changed.md`, and this checkpoint synchronized whenever the boundary changes. +9. Native Android APK/AAB and native iOS IPA delivery remain separate implementation tracks; browser support must not be relabeled as native packaging. +10. Keep README, changelog, release-process/evidence docs, project-sync/desktop/source/test references, repository-reference corpus, `what_changed.md`, and this checkpoint synchronized whenever the release boundary changes. ## Continuation rule -Future sessions should inspect the actual current `main` head, read this file plus `what_changed.md`, and consult the repository/source/test/automation/configuration references before modifying a subsystem. Continue from repository evidence instead of re-opening completed work, and never turn configured automation or committed tests into claimed passing evidence without an observed run. +Future sessions should inspect the actual current `main` and any active release branch, read this file plus `what_changed.md`, and consult the repository/source/test/automation/configuration/release references before modifying a subsystem. Continue from repository evidence instead of re-opening completed work, and never turn configured automation or committed tests into claimed passing evidence without an observed run for the exact checkpoint. From a456bf41813f20110500a1d3b5b34773239c40c9 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:11:40 +0530 Subject: [PATCH 06/48] docs(progress): record 2.8.5 preparation work --- what_changed.md | 142 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 107 insertions(+), 35 deletions(-) diff --git a/what_changed.md b/what_changed.md index 23fb69d..1405540 100644 --- a/what_changed.md +++ b/what_changed.md @@ -3,12 +3,99 @@ This file records the **current** DocMergeForge development continuation. Earlier detailed records are preserved so this top-level checkpoint remains fast to review: - [`docs/history/what_changed-through-2026-08-18.md`](docs/history/what_changed-through-2026-08-18.md) — earlier repository development history; -- [`docs/history/what_changed-through-2026-08-20-cross-platform.md`](docs/history/what_changed-through-2026-08-20-cross-platform.md) — the complete top-level record through the responsive cross-platform web/security continuation immediately preceding this one. +- [`docs/history/what_changed-through-2026-08-20-cross-platform.md`](docs/history/what_changed-through-2026-08-20-cross-platform.md) — the complete top-level record through the responsive cross-platform web/security continuation immediately preceding desktop synchronization. A source change, test file, workflow definition, or commit is implementation/configuration evidence only. It is not represented as a passing CI, packaged-app, browser/device, accessibility, external-office, signing, notarization, or production-release result unless that exact evidence was observed. +## 2026-08-24 — Version 2.8.5 release preparation + +### Goal + +Prepare DocMergeForge package/runtime/release metadata for `2.8.5`, remove stale continuation guidance, and close the remaining GitHub Actions generation mismatch without claiming unobserved release acceptance. + +This work is based on `main` checkpoint `aac5bf6d275991e21b68e15f5ad31f084fbc72e2` and is being developed on `release/2.8.5-prep` for review before merge. + +### Version metadata synchronized + +- `pyproject.toml` now declares `version = "2.8.5"`. +- `src/docmergeforge/__init__.py` now exposes `__version__ = "2.8.5"`. +- `tests/unit/test_version_metadata.py` retains package/runtime equality checking and now pins `EXPECTED_RELEASE_VERSION = "2.8.5"` so candidate drift fails explicitly. +- The existing pre-alpha classifier remains conservative. The numeric version is not treated as proof of production readiness. + +### Project Sync Safety workflow aligned + +`.github/workflows/project-sync-safety.yml` was the remaining focused workflow using older GitHub Action generations. It now uses: + +```text +actions/checkout@v7 +actions/setup-python@v7 +``` + +This matches the maintained Node-24-era action generation documented elsewhere in the repository. Dependabot PR #3 and PR #4 propose the same two one-line upgrades independently; after this combined release-preparation change is merged, those PRs can be closed as superseded rather than merged separately. + +### Recent-project synchronization is complete + +The earlier continuation record listed a Recent Projects synchronization shortcut as possible future work. That item is now complete on `main`. + +`ProjectSyncMainWindow` exposes two stable accessible actions: + +- **Synchronize Project Sources** for browsing to a project JSON; +- **Synchronize Recent Project** for selecting from maintained recent-project history. + +Both routes call the same `_synchronize_project_path(...)` workflow. They therefore preserve the shared `project.sync` planner/apply semantics, full preview, same-kind duplicate blocking, unchanged no-op behavior, separate removal approval, exact revision propagation, backup behavior, stale-write failure surfacing, and metadata-only mutation boundary. + +The integration suite covers both browse and recent-project routing in addition to the synchronization safety contract. + +### Project checkpoint synchronized + +`PROJECT_STATE.md` now records: + +- target `main` plus active `release/2.8.5-prep` branch; +- package version `2.8.5`; +- release-preparation base `aac5bf6d275991e21b68e15f5ad31f084fbc72e2`; +- the Recent Projects shortcut as completed rather than future work; +- exact candidate verification gates that still require observed evidence. + +### Focused commits in this continuation + +- `253aed48f661b5009c95d2a298cb7038081ac1f8` — `ci(sync): align focused workflow action majors`. +- `4eda83909a62fb2fd6dbf6a3ca05da6e50b681a8` — `chore(version): prepare package metadata for 2.8.5`. +- `1823ff8bf406055298dbdaed82f84a83d836196a` — `chore(version): expose 2.8.5 package version`. +- `67015d621ca4b86ab4731b79dded7e0badd967e8` — `test(version): pin 2.8.5 release candidate metadata`. +- `1ee0e76d6714cd4c2c15c02dc6c8edaeab918454` — `docs(state): advance checkpoint to 2.8.5 preparation`. + +### Verification boundary for 2.8.5 + +No fresh candidate-head pass is claimed yet. Before `2.8.5` is treated as release-verified, observe and review the exact candidate commit for the applicable gates, including: + +- Quality on Python 3.12 and 3.13; +- Project Sync Safety on Ubuntu, Windows, and macOS; +- 120-Part Regression; +- Build Smoke on Ubuntu, Windows, and macOS; +- Security/CodeQL; +- Package Desktop and Onefile Acceptance if those artifacts are distributed; +- downloaded-artifact verification; +- release documentation/reference checks. + +Human/production gates remain independent: representative device/browser acceptance, clean-machine desktop UX, human accessibility, real-world office fidelity, claimed-scale stress evidence, Windows signing, macOS signing/notarization, and any installer/distribution acceptance. + +Historical workflow runs remain evidence only for their exact historical checkpoints; they are not relabeled as `2.8.5` evidence. + +### Remaining next work after this preparation pass + +1. Finish release-document synchronization (`CHANGELOG.md`, README release-status wording, release-process/evidence wording) for `2.8.5`. +2. Open/review the release-preparation PR and observe its exact CI results. +3. Fix any candidate-head lint/format/type/test/docs/reference failure without weakening checks. +4. Run/review cross-platform regression, build, security, packaging, and downloaded-artifact gates appropriate to the intended `2.8.5` distribution. +5. Continue representative browser/device acceptance; browser support is not native APK/AAB/IPA packaging. +6. Continue native-office fidelity, measured large-stress, human accessibility, clean-machine, signing/notarization, and distribution acceptance independently. +7. Keep synchronized project discovery/business rules centralized in `project.sync`; do not fork browse/recent/CLI semantics. +8. If simultaneous multi-writer project editing becomes required, design a coordinated lock/revision protocol rather than relabeling the optimistic SHA-256 stale-write guard. + ## 2026-08-20 — Guarded desktop project synchronization +> Historical continuation below. Its original “remaining next work” list is superseded by the `2026-08-24` section above where later commits completed the Recent Projects shortcut and began `2.8.5` preparation. + ### Goal completed The desktop application now exposes the CLI project's review-first synchronization model instead of requiring desktop users to switch to the command line when a saved project's source membership changes. @@ -50,24 +137,17 @@ The implementation deliberately **reuses** the existing `docmergeforge.project.s ### Changed -- `pyproject.toml` now routes the public desktop console script through the maintained synchronization-enabled entry: +- `pyproject.toml` routes the public desktop console script through the maintained synchronization-enabled entry: ```text docmergeforge-gui = "docmergeforge.ui.desktop_entry:main" ``` -- `src/docmergeforge/ui/packaged_entry.py` now: - - delegates normal packaged startup to the synchronization-enabled desktop entry; - - instantiates `ProjectSyncMainWindow` during packaged GUI smoke; - - retains the existing real temporary PDF/DOCX publication smoke after GUI initialization. -- `src/docmergeforge/packaging/desktop.py` now requires all maintained desktop startup modules during `build_desktop.py --check`: - - `ui/main.py`; - - `ui/desktop_entry.py`; - - `ui/project_sync_dialog.py`; - - `ui/packaged_entry.py`. -- `tests/unit/test_build_desktop.py` now protects those packaging prerequisites. -- `tests/unit/test_version_metadata.py` now pins all maintained public console entry points so metadata drift cannot silently bypass the desktop synchronization entry. -- The root `README.md` now publicly describes guarded desktop synchronization, its metadata-only boundary, duplicate blocking, second removal approval, backup behavior, and exact-revision stale-write protection. +- `src/docmergeforge/ui/packaged_entry.py` delegates normal packaged startup to the synchronization-enabled desktop entry, instantiates `ProjectSyncMainWindow` during packaged GUI smoke, and retains the existing real temporary PDF/DOCX publication smoke after GUI initialization. +- `src/docmergeforge/packaging/desktop.py` requires all maintained desktop startup modules during `build_desktop.py --check`: `ui/main.py`, `ui/desktop_entry.py`, `ui/project_sync_dialog.py`, and `ui/packaged_entry.py`. +- `tests/unit/test_build_desktop.py` protects those packaging prerequisites. +- `tests/unit/test_version_metadata.py` pins all maintained public console entry points so metadata drift cannot silently bypass the desktop synchronization entry. +- The root `README.md` describes guarded desktop synchronization, its metadata-only boundary, duplicate blocking, second removal approval, backup behavior, and exact-revision stale-write protection. ### Shared synchronization safety preserved @@ -100,11 +180,11 @@ Updated: - `docs/test-suite-reference.md`; - `docs/repository-reference-cross-platform.md`. -The repository-reference addendum explicitly catalogs the new desktop runtime/test paths and this archived prior progress record so the tracked-file documentation contract remains maintainable. +The repository-reference addendum catalogs the new desktop runtime/test paths and archived prior progress record so the tracked-file documentation contract remains maintainable. ### Packaging and entry-point hardening -The new desktop feature is not source-only: +The desktop feature is not source-only: - editable/wheel installs launch it through `docmergeforge-gui`; - packaged application startup launches the same synchronization-enabled window; @@ -112,7 +192,7 @@ The new desktop feature is not source-only: - packaging preflight refuses a repository missing the new desktop entry/dialog modules; - metadata regression tests pin CLI, GUI, and web console targets. -### Commits in this continuation before this record reset +### Commits in that continuation before the record reset - `f6bb8ffcf72500655006c392844963fcb6459d03` — `feat(ui): add project synchronization preview dialog`. - `1ec59c4923961b8a34e8a3badaabc993937fc2c8` — `docs(reference): catalog desktop project sync dialog`. @@ -137,24 +217,16 @@ The new desktop feature is not source-only: - `8ac078d1f0ccc5aa014cea4a551713cb0ff12046` — `docs(readme): expose guarded desktop project synchronization`. - `ceb27871b64c500121d2fb89da1317dc21b32171` — `docs(reference): catalog archived cross-platform progress record`. -One intermediate `pyproject.toml` write accidentally added Ruff's `S` rule family while changing the GUI entry point. It was immediately reverted in the next focused commit (`b8328a7...`). The repository's maintained Ruff rule set remains `E/F/I/B/UP/SIM/C4`; this continuation does not weaken or silently broaden lint policy. +One intermediate `pyproject.toml` write accidentally added Ruff's `S` rule family while changing the GUI entry point. It was immediately reverted in the next focused commit (`b8328a7...`). The maintained Ruff rule set remains `E/F/I/B/UP/SIM/C4`; that continuation did not weaken or silently broaden lint policy. -### Verification status +### Historical verification status - Continuation base: `9775190f38e613e33f20aafc82b678a1ca3a233d`. -- Latest implementation/documentation checkpoint immediately before this active-record reset: `ceb27871b64c500121d2fb89da1317dc21b32171`. -- A compare from the continuation base through the pre-record checkpoint shows the expected GUI/project-sync/packaging/test/documentation surfaces and no unrelated document-engine rewrite. -- The public repository remains version `0.1.0` / pre-stable. -- Branch metadata inspected during this continuation reports `main` as not protected and required status checks disabled at the repository-rules layer. This is repository-administration state, not an application defect; enabling branch protection remains an administrative decision. -- The execution environment could not obtain a raw GitHub archive/checkout, so no local current-head Ruff, Black, mypy, docs checker, repository-reference checker, or pytest run is claimed. -- GitHub workflow definitions remain configured to run Quality on `main`, but configured automation is not treated as an observed passing current-head result. - -### Remaining next work - -1. Observe a current-head Quality run and fix any Ruff/Black/mypy/docs/reference/pytest failure without weakening the checks. -2. Review Build Smoke/package results for the synchronization-enabled desktop entry and fix any platform-specific startup or PyInstaller issue found by real runners. -3. Consider a recent-project shortcut into synchronization only if it can preserve the same explicit preview/removal/stale-write approvals; do not bypass the current safety gates for convenience. -4. Keep the desktop and CLI synchronization semantics shared in `project.sync`; do not fork them into UI-specific business logic. -5. Perform representative manual browser/device acceptance for the responsive cross-platform client. -6. Continue independent release gates for native-office fidelity, measured multi-gigabyte stress, human accessibility, clean-machine packaged apps, Windows signing, and macOS signing/notarization. -7. Do not claim `v1.0.0`, native mobile APK/AAB/IPA delivery, universal multi-writer project locking, or production certification until corresponding implementation and acceptance evidence exists. +- Pre-record checkpoint: `ceb27871b64c500121d2fb89da1317dc21b32171`. +- At that checkpoint the package metadata was still `0.1.0`; the later `2026-08-24` continuation above supersedes that version state. +- Branch metadata reported `main` as not protected and required status checks disabled at the repository-rules layer. +- No current-candidate test result should be inferred from the existence of committed tests/workflows. + +### Historical next-work list + +The original list included current-head Quality/build/package review, the then-unimplemented Recent Projects shortcut, manual browser/device acceptance, shared synchronization semantics, and independent release gates. The shortcut is now complete; the remaining applicable gates are carried forward in the `2026-08-24` section above. From 55039559d7f444ddfc528c1986f4de7deeea18d6 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:12:42 +0530 Subject: [PATCH 07/48] docs(release): define evidence-first 2.8.5 candidate policy --- docs/release-process.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/release-process.md b/docs/release-process.md index 8893889..e0b6134 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -1,8 +1,8 @@ # Release Process -This document defines the evidence required to move DocMergeForge from a development checkpoint to a release candidate and, eventually, a stable `v1.0.0` release. +This document defines the evidence required to move DocMergeForge from a development checkpoint to a release candidate and, eventually, an intentionally production-accepted release. -A release is not complete merely because source tests pass or PyInstaller creates an archive. +A release is not complete merely because source tests pass, a version number changes, or PyInstaller creates an archive. ## Release evidence levels @@ -17,7 +17,9 @@ Documentation, changelogs, and releases must not collapse these levels into a si ## Versioning -The project follows semantic-versioning intent. The package remains pre-stable (`0.x`) while the release matrix is being completed. `1.0.0` is reserved for the first intentionally accepted stable public contract. +The current release-preparation target is `2.8.5`. DocMergeForge uses semantic-version-shaped package identifiers, but the repository's evidence model remains authoritative for readiness: a major version greater than zero or one does **not** by itself mean that human/production acceptance, signing/notarization, native mobile packaging, external-office fidelity, or claimed-scale stress gates have passed. + +The distribution classifier and release documentation must remain conservative until the corresponding evidence is accepted. For `2.8.5`, treat package/runtime metadata as a candidate identifier first; promote/tag/publish only after the intended release gates for that distribution claim are green and reviewed. ## 1. Freeze release scope @@ -29,13 +31,16 @@ Review/update as appropriate: ```text pyproject.toml +src/docmergeforge/__init__.py +tests/unit/test_version_metadata.py CHANGELOG.md README.md docs/ +PROJECT_STATE.md what_changed.md ``` -Every documented command and support claim must match the candidate implementation. +Every documented command and support claim must match the candidate implementation. Package metadata and runtime `__version__` must agree, and the release candidate should have an explicit regression pin so accidental version drift fails before publication. ## 3. Source quality and documentation gate @@ -47,6 +52,7 @@ ruff check . black --check --diff . mypy src/docmergeforge python scripts/check_docs_links.py +python scripts/check_repository_reference.py pytest --cov=docmergeforge --cov-report=term-missing ``` @@ -111,7 +117,7 @@ Run: 32033135355 Checkpoint: 59dc14bbf1d4301177e475ac350694bdd9d90ada ``` -All Windows/macOS/Ubuntu build-host and fresh-runner jobs passed. +All Windows/macOS/Ubuntu build-host and fresh-runner jobs passed for that historical checkpoint. Re-run/review candidate-appropriate packaging evidence before attributing it to `2.8.5`. ## 13. Optional onefile gate @@ -124,7 +130,7 @@ Run: 32033541414 Checkpoint: dc624e23d07e0ce94ef345245630d153ee60091a ``` -All Windows/macOS/Ubuntu build-host and fresh-runner jobs passed. +All Windows/macOS/Ubuntu build-host and fresh-runner jobs passed for that historical checkpoint. Do not relabel it as `2.8.5` evidence unless the exact candidate commit is the checkpoint being verified. ## 14. Build provenance and SBOM gate @@ -149,7 +155,7 @@ Before a production support claim, use representative clean end-user machines/VM ## 16. Platform signing/notarization gate -Current artifacts are explicitly unsigned development builds. +Current artifacts are explicitly unsigned development builds unless final-stage evidence says otherwise. ### Windows @@ -185,7 +191,7 @@ Release notes should state supported platforms/architectures/build modes, worklo A `v*` tag can trigger packaging, but the tag itself is not acceptance and does not make current artifacts signed. -Tag only the chosen reviewed commit after required gates for the release claim are green/accepted. +Tag only the chosen reviewed commit after required gates for the release claim are green/accepted. For the current cycle, do not create or describe `v2.8.5` as accepted merely because package metadata says `2.8.5`. ## 21. Post-release verification @@ -199,9 +205,11 @@ After publishing through the real user-facing channel: 6. confirm no private/debug files were uploaded; 7. retain run IDs, provenance/SBOM/checksums, trust evidence, and human acceptance records. -## Stable `v1.0.0` gate +## Production-acceptance gate + +Do not claim a production-accepted release until required areas for the intended support statement are intentionally accepted, including core merge correctness, transaction/recovery safety, representative large/stress workloads, real-world fidelity, human accessibility, downloaded-artifact and human clean-machine package acceptance, production signing/notarization where distributed, and complete documentation/support/security processes. -Do not claim `v1.0.0` until required areas for the intended support statement are intentionally accepted, including core merge correctness, transaction/recovery safety, representative large/stress workloads, real-world fidelity, human accessibility, downloaded-artifact and human clean-machine package acceptance, production signing/notarization where distributed, and complete documentation/support/security processes. +This gate applies to `2.8.5` regardless of its numeric major version. ## Release evidence template @@ -210,6 +218,7 @@ Version/tag: Commit SHA: Date: Quality run: +Project Sync Safety run: 120-Part Regression run: Build Smoke run: Security run: From 3c7ca61672be48255cb159aec81fe98e7eb11f46 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:16:00 +0530 Subject: [PATCH 08/48] style(discovery): apply maintained Black formatting --- src/docmergeforge/discovery/scanner.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/docmergeforge/discovery/scanner.py b/src/docmergeforge/discovery/scanner.py index e5f099f..51abc7a 100644 --- a/src/docmergeforge/discovery/scanner.py +++ b/src/docmergeforge/discovery/scanner.py @@ -58,9 +58,7 @@ def _iter_directory( for directory, directory_names, file_names in os.walk(root, followlinks=False): directory_path = Path(directory) directory_names[:] = [ - name - for name in directory_names - if not _is_excluded(directory_path / name, excluded) + name for name in directory_names if not _is_excluded(directory_path / name, excluded) ] for name in file_names: path = directory_path / name From 2eb2fbf448a91451169c37b037e317a4a7d1b323 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:16:25 +0530 Subject: [PATCH 09/48] style(sync): apply maintained Black formatting --- src/docmergeforge/project/sync.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/docmergeforge/project/sync.py b/src/docmergeforge/project/sync.py index f9683d2..4e58fb1 100644 --- a/src/docmergeforge/project/sync.py +++ b/src/docmergeforge/project/sync.py @@ -78,7 +78,9 @@ def to_dict(self) -> dict[str, object]: } -def _eligible_documents(project: MergeProject, discovered: list[InputDocument]) -> list[InputDocument]: +def _eligible_documents( + project: MergeProject, discovered: list[InputDocument] +) -> list[InputDocument]: start = project.settings.expected_start end = project.settings.expected_end unique: list[InputDocument] = [] @@ -127,9 +129,7 @@ def _missing_parts( end: int, ) -> tuple[int, ...]: found = { - item.part.number - for item in documents - if item.kind == kind and item.part.number is not None + item.part.number for item in documents if item.kind == kind and item.part.number is not None } if not found: return () @@ -157,9 +157,7 @@ def plan_project_sync( proposed_set = set(proposed_keys) added = tuple( - path - for path, key in zip(proposed, proposed_keys, strict=True) - if key not in current_set + path for path, key in zip(proposed, proposed_keys, strict=True) if key not in current_set ) removed = tuple( path for path, key in zip(current, current_keys, strict=True) if key not in proposed_set From 2d85c31ea341be976a7cacf341bf957b3ec7e9ce Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:16:41 +0530 Subject: [PATCH 10/48] style(test): format scanner exclusion regression --- tests/unit/test_scanner_exclusions.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/unit/test_scanner_exclusions.py b/tests/unit/test_scanner_exclusions.py index 8cf186c..c9b3df5 100644 --- a/tests/unit/test_scanner_exclusions.py +++ b/tests/unit/test_scanner_exclusions.py @@ -107,9 +107,7 @@ def test_non_recursive_iter_files_still_honors_excluded_root(tmp_path: Path) -> included.write_text("one", encoding="utf-8") excluded_file.write_text("two", encoding="utf-8") - discovered = list( - scanner.iter_files([source], recursive=False, exclude_roots=[excluded]) - ) + discovered = list(scanner.iter_files([source], recursive=False, exclude_roots=[excluded])) assert discovered == [included] From c9f9c3995558d0f087ea692fa322e70ce5cdcf2b Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:18:07 +0530 Subject: [PATCH 11/48] style(cli): format validation diagnostics --- src/docmergeforge/cli/main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/docmergeforge/cli/main.py b/src/docmergeforge/cli/main.py index 65b6c8f..480a58d 100644 --- a/src/docmergeforge/cli/main.py +++ b/src/docmergeforge/cli/main.py @@ -278,9 +278,7 @@ def _run_direct_merge(args: argparse.Namespace) -> int: "ready": False, "missing": validation_result.missing_parts, "duplicates": validation_result.duplicate_parts, - "diagnostics": [ - item.to_dict() for item in validation_result.diagnostics - ], + "diagnostics": [item.to_dict() for item in validation_result.diagnostics], }, indent=2, ) From 01d10892af0a5f3ba66f57fb32894587dcba8e8d Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:19:31 +0530 Subject: [PATCH 12/48] test(discovery): create real files for pruning regression --- tests/unit/test_scanner_exclusions.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/unit/test_scanner_exclusions.py b/tests/unit/test_scanner_exclusions.py index c9b3df5..083607a 100644 --- a/tests/unit/test_scanner_exclusions.py +++ b/tests/unit/test_scanner_exclusions.py @@ -66,6 +66,11 @@ def test_recursive_iter_files_prunes_excluded_directory_before_descent( source.mkdir() excluded = source / "Master" content = source / "Content" + content.mkdir() + root_file = source / "root.txt" + content_file = content / "Part 1.docx" + root_file.write_text("root", encoding="utf-8") + content_file.write_text("content", encoding="utf-8") directory_names = ["Master", "Content"] walk_calls: list[tuple[Path, bool]] = [] @@ -75,15 +80,15 @@ def fake_walk( followlinks: bool, ) -> Iterator[tuple[str, list[str], list[str]]]: walk_calls.append((root, followlinks)) - yield str(source), directory_names, ["root.txt"] + yield str(source), directory_names, [root_file.name] assert directory_names == ["Content"] - yield str(content), [], ["Part 1.docx"] + yield str(content), [], [content_file.name] monkeypatch.setattr(scanner.os, "walk", fake_walk) discovered = list(scanner.iter_files([source], exclude_roots=[excluded])) - assert discovered == [source / "root.txt", content / "Part 1.docx"] + assert discovered == [root_file, content_file] assert walk_calls == [(source, False)] From 1b03b5aa34092b8ee7dddf6480903502bd2cade7 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:20:14 +0530 Subject: [PATCH 13/48] ci(regression): install integration extras and preserve repo imports --- .github/workflows/regression.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 0199990..545883d 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -28,7 +28,7 @@ jobs: sudo apt-get update sudo apt-get install -y libegl1 - run: python -m pip install --upgrade pip - - run: pip install -e ".[dev]" + - run: python -m pip install -e ".[dev,web]" - run: python scripts/generate_120_fixture.py fixtures/generated/sql-120 - - run: pytest -m "regression or integration" tests/regression tests/integration + - run: python -m pytest -m "regression or integration" tests/regression tests/integration - run: docmergeforge validate --input fixtures/generated/sql-120 --parts 1-120 From ae302a4ee7388d4f84b7c598e97aac7d4f9b0137 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:20:32 +0530 Subject: [PATCH 14/48] ci(quality): preserve repository imports during pytest --- .github/workflows/quality.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 78e9980..cc232db 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -29,11 +29,11 @@ jobs: sudo apt-get update sudo apt-get install -y libegl1 - run: python -m pip install --upgrade pip - - run: pip install -e ".[dev,web]" + - run: python -m pip install -e ".[dev,web]" - run: pre-commit validate-config - run: ruff check . - run: black --check --diff . - run: mypy src/docmergeforge - run: python scripts/check_docs_links.py - run: python scripts/check_repository_reference.py - - run: pytest --cov=docmergeforge --cov-report=term-missing + - run: python -m pytest --cov=docmergeforge --cov-report=term-missing From 254ab015e31806fc85ef6ed5dfa3dfee73198085 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:22:20 +0530 Subject: [PATCH 15/48] docs(progress): record candidate CI fixes --- what_changed.md | 51 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/what_changed.md b/what_changed.md index 1405540..0001324 100644 --- a/what_changed.md +++ b/what_changed.md @@ -56,6 +56,25 @@ The integration suite covers both browse and recent-project routing in addition - the Recent Projects shortcut as completed rather than future work; - exact candidate verification gates that still require observed evidence. +### CI-discovered maintenance fixed without weakening gates + +The first candidate runs exposed pre-existing maintenance drift that was not visible from source inspection alone. The fixes stay inside the maintained contracts rather than suppressing checks: + +1. Project Sync Safety initially failed Black 26 formatting on four existing paths. The branch now applies Black's formatting-only result to: + - `src/docmergeforge/discovery/scanner.py`; + - `src/docmergeforge/project/sync.py`; + - `src/docmergeforge/cli/main.py`; + - `tests/unit/test_scanner_exclusions.py`. + A subsequent Ubuntu focused-safety run observed Black, Ruff, and strict mypy passing on the corrected files. +2. The focused pruning regression then exposed an invalid fixture assumption: its fake `os.walk` yielded names for files/directories that had never been created, while production scanning correctly requires `Path.is_file()`. The test now creates the real root/content files before exercising pruning; production scanner behavior was not weakened. +3. 120-Part Regression exposed two workflow collection defects: + - the integration suite includes FastAPI-backed web tests but the workflow installed only `[dev]`; + - several integration tests import repository-root `scripts`, but the workflow invoked the standalone `pytest` executable. + The workflow now installs `.[dev,web]` and invokes `python -m pytest`, preserving repository-root imports and the actual integration dependency set. +4. Quality now likewise uses `python -m pip` and `python -m pytest` so its execution environment matches the repository import model deterministically. + +These are CI/test-environment corrections, not reductions in coverage or quality rules. + ### Focused commits in this continuation - `253aed48f661b5009c95d2a298cb7038081ac1f8` — `ci(sync): align focused workflow action majors`. @@ -63,10 +82,25 @@ The integration suite covers both browse and recent-project routing in addition - `1823ff8bf406055298dbdaed82f84a83d836196a` — `chore(version): expose 2.8.5 package version`. - `67015d621ca4b86ab4731b79dded7e0badd967e8` — `test(version): pin 2.8.5 release candidate metadata`. - `1ee0e76d6714cd4c2c15c02dc6c8edaeab918454` — `docs(state): advance checkpoint to 2.8.5 preparation`. +- `a456bf41813f20110500a1d3b5b34773239c40c9` — `docs(progress): record 2.8.5 preparation work`. +- `55039559d7f444ddfc528c1986f4de7deeea18d6` — `docs(release): define evidence-first 2.8.5 candidate policy`. +- `3c7ca61672be48255cb159aec81fe98e7eb11f46` — `style(discovery): apply maintained Black formatting`. +- `2eb2fbf448a91451169c37b037e317a4a7d1b323` — `style(sync): apply maintained Black formatting`. +- `2d85c31ea341be976a7cacf341bf957b3ec7e9ce` — `style(test): format scanner exclusion regression`. +- `c9f9c3995558d0f087ea692fa322e70ce5cdcf2b` — `style(cli): format validation diagnostics`. +- `01d10892af0a5f3ba66f57fb32894587dcba8e8d` — `test(discovery): create real files for pruning regression`. +- `1b03b5aa34092b8ee7dddf6480903502bd2cade7` — `ci(regression): install integration extras and preserve repo imports`. +- `ae302a4ee7388d4f84b7c598e97aac7d4f9b0137` — `ci(quality): preserve repository imports during pytest`. ### Verification boundary for 2.8.5 -No fresh candidate-head pass is claimed yet. Before `2.8.5` is treated as release-verified, observe and review the exact candidate commit for the applicable gates, including: +Fresh candidate runs are required after the latest documentation checkpoint. Intermediate observed evidence is intentionally recorded only at the granularity actually seen: + +- Project Sync Safety on Ubuntu, after the formatting commits and before the later test/workflow commits, passed focused Black, Ruff, and strict mypy and then exposed the pruning-fixture failure described above. +- Security dependency review was observed passing on a later candidate head while CodeQL was still running. +- Earlier failed/interrupted runs are diagnostic evidence only and are superseded by newer candidate heads. + +Before `2.8.5` is treated as release-verified, observe and review the exact final candidate commit for the applicable gates, including: - Quality on Python 3.12 and 3.13; - Project Sync Safety on Ubuntu, Windows, and macOS; @@ -83,14 +117,13 @@ Historical workflow runs remain evidence only for their exact historical checkpo ### Remaining next work after this preparation pass -1. Finish release-document synchronization (`CHANGELOG.md`, README release-status wording, release-process/evidence wording) for `2.8.5`. -2. Open/review the release-preparation PR and observe its exact CI results. -3. Fix any candidate-head lint/format/type/test/docs/reference failure without weakening checks. -4. Run/review cross-platform regression, build, security, packaging, and downloaded-artifact gates appropriate to the intended `2.8.5` distribution. -5. Continue representative browser/device acceptance; browser support is not native APK/AAB/IPA packaging. -6. Continue native-office fidelity, measured large-stress, human accessibility, clean-machine, signing/notarization, and distribution acceptance independently. -7. Keep synchronized project discovery/business rules centralized in `project.sync`; do not fork browse/recent/CLI semantics. -8. If simultaneous multi-writer project editing becomes required, design a coordinated lock/revision protocol rather than relabeling the optimistic SHA-256 stale-write guard. +1. Observe the exact final PR-head Quality, Project Sync Safety, 120-Part Regression, Build Smoke, and Security/CodeQL results and fix any remaining failure without weakening maintained gates. +2. Finish optional public release-facing wording in `CHANGELOG.md`/README only where it adds accurate value; `PROJECT_STATE.md`, `what_changed.md`, package/runtime metadata, and release policy are already synchronized to the candidate boundary. +3. Run/review Package Desktop, Onefile Acceptance, and downloaded-artifact gates if those artifacts are intended for the `2.8.5` distribution. +4. Continue representative browser/device acceptance; browser support is not native APK/AAB/IPA packaging. +5. Continue native-office fidelity, measured large-stress, human accessibility, clean-machine, signing/notarization, and distribution acceptance independently. +6. Keep synchronized project discovery/business rules centralized in `project.sync`; do not fork browse/recent/CLI semantics. +7. If simultaneous multi-writer project editing becomes required, design a coordinated lock/revision protocol rather than relabeling the optimistic SHA-256 stale-write guard. ## 2026-08-20 — Guarded desktop project synchronization From c3404fb8669efcbc5b5a3e2b65c9d65ab43806ce Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:25:22 +0530 Subject: [PATCH 16/48] style(ui): wrap desktop sync accessibility text --- src/docmergeforge/ui/desktop_entry.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/docmergeforge/ui/desktop_entry.py b/src/docmergeforge/ui/desktop_entry.py index dfea376..085d0af 100644 --- a/src/docmergeforge/ui/desktop_entry.py +++ b/src/docmergeforge/ui/desktop_entry.py @@ -32,7 +32,8 @@ def __init__(self) -> None: self.sync_project_button = QPushButton("Synchronize Project Sources") self.sync_project_button.setAccessibleName("Synchronize project sources") self.sync_project_button.setAccessibleDescription( - "Browse for a saved project, preview source-selection changes, and optionally apply them." + "Browse for a saved project, preview source-selection changes, " + "and optionally apply them." ) self.sync_project_button.setMinimumHeight(58) self.sync_project_button.clicked.connect(self._synchronize_project) From d77fd9e7bac344757619ff16a78827e11c57f4d9 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:25:55 +0530 Subject: [PATCH 17/48] style(ui): wrap project sync guidance --- src/docmergeforge/ui/project_sync_dialog.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/docmergeforge/ui/project_sync_dialog.py b/src/docmergeforge/ui/project_sync_dialog.py index f19b734..20840a2 100644 --- a/src/docmergeforge/ui/project_sync_dialog.py +++ b/src/docmergeforge/ui/project_sync_dialog.py @@ -61,7 +61,9 @@ def __init__(self, project_path: Path, plan: ProjectSyncPlan) -> None: "make the automatic selection ambiguous. Resolve the duplicates and preview again." ) elif not plan.changed: - guidance = "The saved selected-file list already matches the current automatic proposal." + guidance = ( + "The saved selected-file list already matches the current automatic proposal." + ) elif plan.removed: guidance = ( "Review the removals carefully. Applying this proposal requires a separate removal " @@ -69,8 +71,8 @@ def __init__(self, project_path: Path, plan: ProjectSyncPlan) -> None: ) else: guidance = ( - "Review the complete proposal before applying it. A versioned backup of the project " - "JSON will be created before the guarded update." + "Review the complete proposal before applying it. A versioned backup of the " + "project JSON will be created before the guarded update." ) self.guidance = QLabel(guidance) From a59cacd978e878850912e9dad1fb15d2f9f29976 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:26:03 +0530 Subject: [PATCH 18/48] style(test): normalize UNO process-group imports --- tests/integration/test_lo_uno_process_group.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/test_lo_uno_process_group.py b/tests/integration/test_lo_uno_process_group.py index 2e0dd43..c3f560e 100644 --- a/tests/integration/test_lo_uno_process_group.py +++ b/tests/integration/test_lo_uno_process_group.py @@ -4,7 +4,6 @@ import time import pytest - from docmergeforge.docx import libreoffice_uno_merge From 6f0d412d8e40a12c94c10b4c462a855ae3ee1220 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:27:08 +0530 Subject: [PATCH 19/48] style(test): normalize OOXML risk imports --- tests/unit/test_ooxml_risk.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_ooxml_risk.py b/tests/unit/test_ooxml_risk.py index ed54fc3..7f459cb 100644 --- a/tests/unit/test_ooxml_risk.py +++ b/tests/unit/test_ooxml_risk.py @@ -1,5 +1,5 @@ -import zipfile from pathlib import Path +import zipfile from docmergeforge.validation.ooxml import risky_docx_constructs From 9c50f649f2212f5295f32d879435dcbd587b4df4 Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:27:17 +0530 Subject: [PATCH 20/48] style(test): satisfy canonical URL assertion rule --- tests/unit/test_ui_resources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_ui_resources.py b/tests/unit/test_ui_resources.py index cc407c5..cc7906d 100644 --- a/tests/unit/test_ui_resources.py +++ b/tests/unit/test_ui_resources.py @@ -10,7 +10,7 @@ def test_desktop_support_links_match_canonical_project_values() -> None: assert REPOSITORY_URL == "https://github.com/sanskarIN/DocMergeForge" - assert DOCS_URL == f"{REPOSITORY_URL}/tree/main/docs" + assert f"{REPOSITORY_URL}/tree/main/docs" == DOCS_URL assert BMC_URL == "https://buymeacoffee.com/sanskarIN" assert X_URL == "https://x.com/x_sanskarIN" assert BUSINESS_EMAIL == "sanskarin@outlook.in" From 10a9add3667a16a00ae3384d0bba744c727e718b Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:28:49 +0530 Subject: [PATCH 21/48] style(ui): simplify ordering checkpoint result --- src/docmergeforge/ui/main.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/docmergeforge/ui/main.py b/src/docmergeforge/ui/main.py index 19cbbdb..e2031d4 100644 --- a/src/docmergeforge/ui/main.py +++ b/src/docmergeforge/ui/main.py @@ -254,9 +254,7 @@ def _confirm_project_order(self, project: MergeProject, *, checkpoint: bool = Tr if order_dialog.exec() != int(order_dialog.DialogCode.Accepted): return False project.selected_files = order_dialog.ordered_paths() - if checkpoint and not self._checkpoint_project(project, "ordering"): - return False - return True + return not checkpoint or self._checkpoint_project(project, "ordering") def _new_project(self, initial_source: Path | None = None) -> None: dialog = ProjectSetupDialog(initial_source) @@ -680,4 +678,4 @@ def main() -> int: if __name__ == "__main__": - raise SystemExit(main()) + raise SystemExit(main()) \ No newline at end of file From f36e397ee3a93a94bcb79b6df560c1eafecccc6b Mon Sep 17 00:00:00 2001 From: Sanskar Date: Mon, 24 Aug 2026 14:29:56 +0530 Subject: [PATCH 22/48] style(web): wrap responsive client source lines --- src/docmergeforge/web/app.py | 61 ++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/src/docmergeforge/web/app.py b/src/docmergeforge/web/app.py index 1d534d5..a118d2d 100644 --- a/src/docmergeforge/web/app.py +++ b/src/docmergeforge/web/app.py @@ -45,12 +45,25 @@ input, button { box-sizing: border-box; width: 100%; min-height: 48px; border-radius: 12px; } input { border: 1px solid #46547a; background: #0f1629; color: #eef2ff; padding: 10px 12px; } input[type=file] { padding: 9px; } - button { margin-top: 20px; border: 0; background: #6d7cff; color: white; font-weight: 800; cursor: pointer; } + button { + margin-top: 20px; + border: 0; + background: #6d7cff; + color: white; + font-weight: 800; + cursor: pointer; + } button:disabled { opacity: .55; cursor: progress; } .muted { color: #b7c0d9; } .status { min-height: 28px; margin-top: 16px; font-weight: 650; } .grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); } - .pill { display: inline-block; border: 1px solid #46547a; border-radius: 999px; padding: 6px 10px; margin: 4px 4px 0 0; } + .pill { + display: inline-block; + border: 1px solid #46547a; + border-radius: 999px; + padding: 6px 10px; + margin: 4px 4px 0 0; + } a { color: #aeb8ff; } @media (prefers-color-scheme: light) { body { background: #f4f6fb; color: #182035; } @@ -64,12 +77,25 @@

DocMergeForge

-

Merge PDF or DOCX parts from Windows, macOS, Linux, Android, iPhone/iPad, ChromeOS, or any modern browser.

-

Files are processed by the DocMergeForge Python host you connected to. The default server binds only to this computer; LAN use requires an access token.

+

+ Merge PDF or DOCX parts from Windows, macOS, Linux, Android, iPhone/iPad, ChromeOS, + or any modern browser. +

+

+ Files are processed by the DocMergeForge Python host you connected to. The default server + binds only to this computer; LAN use requires an access token. +

- +
@@ -83,8 +109,16 @@
- -

Leave blank for the loopback-only host. LAN tokens stay in this browser tab session and are sent only in the merge request header.

+ +

+ Leave blank for the loopback-only host. LAN tokens stay in this browser tab session and + are sent only in the merge request header. +

@@ -100,7 +134,9 @@