From 78934b17d8c43866626a71fe0f52667221894cbb Mon Sep 17 00:00:00 2001 From: mbx30 <212453881+mberrys@users.noreply.github.com> Date: Sun, 27 Sep 2026 15:27:00 -0700 Subject: [PATCH 1/2] fix(history): keep accepted outputs reported when retention fails A retention failure after an accepted rollback or repair no longer hides the published result: the editor still opens the restored revision and refreshes its rollback points, and repair writes its report and registers its outputs before enforcing retention. The per-run preflight coverage claim again states that Loop makes no formal GWG conformance claim for every profile family, alongside the sheetfed-offset/packaging limit. Co-Authored-By: Claude Opus 5.5 --- LoopEditor/editorhost.cpp | 20 ++++++++++++-------- LoopLibCore/sources/preflightengine.cpp | 7 ++++--- PdfTool/pdftoolrepair.cpp | 20 +++++++++++--------- changes/cc-code-review-ebc857.md | 4 ++++ 4 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 changes/cc-code-review-ebc857.md diff --git a/LoopEditor/editorhost.cpp b/LoopEditor/editorhost.cpp index 4bf452777..46321a1f5 100644 --- a/LoopEditor/editorhost.cpp +++ b/LoopEditor/editorhost.cpp @@ -2476,19 +2476,23 @@ bool EditorHost::requestFixRollback(const QString& rollbackId) return false; } + // The restored revision and its rolled-back event are already published, so a retention + // failure is reported alongside them rather than hiding the new revision. const pdf::PDFHistoryRetentionResult retention = history.enforceRetention({}, artifacts); - if (!retention.success) + const QString revision = point->documentRevisionDigest.left(12); + const QString destinationName = QFileInfo(destination).fileName(); + if (retention.success) { - announceDocumentState(tr("The revision was restored, but history retention could not be enforced: %1") - .arg(retention.errorMessage)); - return false; + announceDocumentState(tr("Returned to revision %1 as %2.").arg(revision, destinationName)); + } + else + { + announceDocumentState(tr("Returned to revision %1 as %2, but history retention could not be enforced: %3") + .arg(revision, destinationName, retention.errorMessage)); } - - announceDocumentState(tr("Returned to revision %1 as %2.") - .arg(point->documentRevisionDigest.left(12), QFileInfo(destination).fileName())); openFileUrl(QUrl::fromLocalFile(destination)); refreshFixRollbackPoints(); - return true; + return retention.success; } void EditorHost::discardActionListPlan() diff --git a/LoopLibCore/sources/preflightengine.cpp b/LoopLibCore/sources/preflightengine.cpp index 8b8889e43..5ff19af4c 100644 --- a/LoopLibCore/sources/preflightengine.cpp +++ b/LoopLibCore/sources/preflightengine.cpp @@ -917,9 +917,10 @@ QJsonObject preflightCoverageScopeFor(const PreflightProfileData& profile) } } return QJsonObject{ - { QStringLiteral("claim"), QStringLiteral("This run does not evaluate formal GWG 2022/2024 conformance for " - "sheetfed-offset or packaging. A clean result covers only its " - "enabled checks, not either family certificate.") }, + { QStringLiteral("claim"), QStringLiteral("Loop does not claim formal GWG conformance. This run does not " + "evaluate GWG 2022/2024 certificate requirements for " + "sheetfed-offset or packaging; a clean result covers only its " + "enabled checks.") }, { QStringLiteral("matrix_id"), QStringLiteral("loop-gwg-pdfx-v1") }, { QStringLiteral("enabled_checks"), checkIds } }; diff --git a/PdfTool/pdftoolrepair.cpp b/PdfTool/pdftoolrepair.cpp index 38bdeb887..0410d47b5 100644 --- a/PdfTool/pdftoolrepair.cpp +++ b/PdfTool/pdftoolrepair.cpp @@ -806,15 +806,6 @@ PDFToolExitCode PDFToolRepair::execute(const PDFToolOptions& options) return PDFToolExitCode::ProcessingFailure; } - const pdf::PDFHistoryRetentionResult retention = operationHistory.enforceRetention({}, historyArtifacts); - if (!retention.success) - { - reportDiagnostic(options, PDFToolDiagnosticSeverity::Error, QStringLiteral("history.retention-failed"), - QStringLiteral("The repair history was recorded, but retention could not be enforced: %1") - .arg(retention.errorMessage)); - return PDFToolExitCode::ProcessingFailure; - } - if (!options.repairReportFile.isEmpty()) { QString reportError; @@ -841,6 +832,17 @@ PDFToolExitCode PDFToolRepair::execute(const PDFToolOptions& options) { PDFConsole::writeText(QString::fromUtf8(QJsonDocument(reportJson).toJson(QJsonDocument::Indented)), options.outputCodec); } + + // Retention runs after the accepted output is fully reported so a retention failure + // cannot suppress the repair report or output registration. + const pdf::PDFHistoryRetentionResult retention = operationHistory.enforceRetention({}, historyArtifacts); + if (!retention.success) + { + reportDiagnostic(options, PDFToolDiagnosticSeverity::Error, QStringLiteral("history.retention-failed"), + QStringLiteral("The repair history was recorded, but retention could not be enforced: %1") + .arg(retention.errorMessage)); + return PDFToolExitCode::ProcessingFailure; + } return PDFToolExitCode::Success; } diff --git a/changes/cc-code-review-ebc857.md b/changes/cc-code-review-ebc857.md new file mode 100644 index 000000000..6b54e819b --- /dev/null +++ b/changes/cc-code-review-ebc857.md @@ -0,0 +1,4 @@ +Category: fixed +Audience: users managing PDF operation history and reading preflight reports +Breaking-Change: no +Summary: Keep the restored revision open and the repair report written when history retention fails after an accepted rollback or repair, and restore the general "no formal GWG conformance" statement in every preflight report's coverage claim. From 05d628b5211eb62c897a59a94f1da0e74ae6437a Mon Sep 17 00:00:00 2001 From: mbx30 <212453881+mberrys@users.noreply.github.com> Date: Sun, 27 Sep 2026 15:27:38 -0700 Subject: [PATCH 2/2] chore(changes): add evidence manifest for retention reporting fix Co-Authored-By: Claude Opus 5.5 --- changes/cc-code-review-ebc857.evidence.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 changes/cc-code-review-ebc857.evidence.yaml diff --git a/changes/cc-code-review-ebc857.evidence.yaml b/changes/cc-code-review-ebc857.evidence.yaml new file mode 100644 index 000000000..fc9edfdf8 --- /dev/null +++ b/changes/cc-code-review-ebc857.evidence.yaml @@ -0,0 +1,17 @@ +format_version: 1 +kind: evidence +claims: + - id: retention-failure-keeps-published-output + evidence: + - unit:agent-policy:pdftool + - unit:agent-policy:pagemaster + - unit:agent-policy:quick + - id: core-coverage-claim + evidence: + - unit:agent-policy:core + - architecture:docs/generated/architecture-catalog.json + - security:scripts/ci/check_source_integrity.py + - differential:UnitTestsConversionOracle +unresolved: + - core:scripts/ci/check_independent_validation_gate.py + - Focused Qt builds and tests (UnitTestsEditorHost, UnitTestsRepairOperatorAcceptance, UnitTestsPreflightEngine) require a configured build directory; this worktree has none.