Repository navigation
Conversation
Complete G00 repository governance and provenance (#108)
#231) The descriptor availability flag is the handler gate: CommandCatalog refuses a handler for a declared id and invoke() answers command/not-implemented, so a KEEP or ABSORB action that is still declared is a menu entry that does nothing. scripts/verify-command-catalog.py now requires every KEEP/ABSORB action to be implemented or listed in docs/shell-handler-coverage.json, the baseline that records today's 70 gaps and may only shrink. --record-ratchet rewrites it. Negative-case tests prove each rule can fail; ci.yml and check-change.py report the check as whole-tree evidence.
… the live epic (#231) The G00 provenance repair re-homed the absorbed plugin rows; these two ADVANCED rows were left null while their replacement surfaces (signing in loop-fix, the scanner document workflow) are still pending, so no live issue owned them.
#232) Text and Measure join the closed InteractionTool vocabulary as their own InteractionKinds: a text selection is a typed, revision-fenced TextSelection resolved through Core's text layout in reading order, and a measurement is a typed revision-fenced Measurement in production units that never becomes a DragSession. The nine actionSelect*/CopyText/GoTo*Line/Screenshot/ExtractImage commands are bound; screenshot and image extraction write through the atomic writer and refuse to overwrite; a page without a text layer reports text/no-text-layer instead of copying an empty string.
) Five actionColor* display modes become presentation-only filters applied in CanvasNodeBuilder::syncTiles over admitted surfaces, converted with Core's own PDFColorConvertor, marked as simulations in the fidelity indicator and never reachable as production evidence. Soft proof renders through a local LittleCMS proofing CMS behind its own surface identity (withSoftProofMarker), shows the profile identity, and a missing or unreadable output intent is a visible state. Plates expose Core's separations with visibility and isolation state that never moves the revision, and the ink-coverage readout measures named channels at a page point.
One typed QSettings-backed store with confirmed reset-to-factory and visible repair of invalid persisted values; actionOptions, actionResetToFactorySettings, actionCollectDiagnostics, the six render-option toggles and the text-block/line views are bound and developer-gated; the ADR-006 diagnostics bundle comes from Core's PDFDiagnosticsCollector. The five KEEP render options are reclassified ADVANCED with rationale and the host routes menus from the manifest's menu_group, so they are reachable in a developer profile only.
The implemented-descriptor pin is now 51 (26 + display modes + select/copy/ capture + settings/diagnostics), and the handler-coverage baseline is re-recorded from the merged manifest: 51 KEEP/ABSORB commands remain.
…al (#232, #238) The shell keyboard test pinned "measure" as an unknown tool; it is a real vocabulary member now, so the negative case moves to "lasso" and the test asserts both new tools route to the controller. The new host case proves image extraction refuses to overwrite an existing file and leaves it byte-identical. The PR fragment and evidence manifest cover the integrated slices.
…tion publish gate List annotations from the open revision in a read-only review column and paint them in their own overlay band, bounded so findings and selection primitives keep their budget, with page-region navigation from the list. Verify document signatures off the UI thread and reduce results to five distinct operator-facing states behind a request/generation/revision-fenced token. Disclose save-policy signature invalidation in the correction-plan preview and the approval, and refuse to publish an invalidating plan over a signed document until the exact plan digest is acknowledged.
…ignature-review L03-11: read-only annotation review and signature status with an invalidation publish gate (#125)
…tory Present Quick Undo and Redo as governed revision history
Reconcile the EditorHost constructor: settings come first, then the parent and the recipes directory dev added, so existing dev call sites pass the null settings argument explicitly. Keep both sides' members in the editor host. Keep the undo and redo handlers from dev in the command catalog and drop them from the handler ratchet baseline, which now records 49 gaps. The facade test expects the 53 implemented commands. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
Keep both published-output records side by side. The Action List worker still records the in-memory published bytes that the export and receipt use, and now also records the published path that the undo and redo history tracks. The editor host clears and sets both together. Both sides' tests stay, the command catalog takes the union of the two branches' implemented commands, and the facade test expects the 30 implemented commands. The quick PDF parity note lists print and export and undo and redo as done. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
The editor host constructor now takes the settings store first, then the parent and recipes directory. A test added from dev still used the old two-argument form, which failed to compile and stopped UnitTestsEditorHost from being built. Pass a null settings argument at each recipe-path call. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
The editor host constructor now takes the settings store first, then the parent and recipes directory. The merged tests still used the old two-argument form, which fails to compile. Pass a null settings argument at each recipe-path call. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
The previous commit's regex matched calls that already passed the settings argument and inserted a second one, which produced four-argument calls that do not compile and break the clang-format check. Restore one null settings argument per recipe-path call. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
The settings-first constructor exists only on the epic branch. This branch still builds against dev, where the constructor takes the parent and the recipes directory, so the test calls I changed here do not compile. Restore the calls to the dev form. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
…export Add Quick print-to-PDF and exact document exports
Bring in the print and export commands from #263. Keep this branch's finish steps and availability updates alongside dev's document output step and the print and export availability. Keep both sides' editor host tests, with the print and export tests first and the display-mode test after them. Take the union of both branches' implemented commands and regenerate the handler ratchet, which now records 48 gaps. The facade test expects the 55 implemented commands. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
feat(quick): handler-coverage gate and read-only surfaces (#231 PR 1)
Records the #234 precondition: annotation, bookmark, link, form, attachment and metadata edits are direct Core mutations through CommandCatalog producing a new revision (fenced, one history event per edit), not planned Fix operations; adds the 013 row missing from the ADR index.
…er-edit history (#234)
#231 PR 2) Cherry-picks the three slice commits and repairs the conflict regions with complete blocks from each slice: one facade gateway per family (unified in follow-up), the 39 implemented ids, expected_action_count 109 -> 113, the handler ratchet re-recorded to 13, and the PR fragment plus evidence manifest.
…uest (#231 PR 2, ADR-014) Collapses the three family gateways into the single DirectEditRequest / DirectEditOutcome / DocumentFacade::applyDirectEdit shape ADR-014 records, dispatching by edit kind to the annotation, outline and document helpers. Refusal codes and fence order per family are unchanged; all call sites and the facade tests are adapted.
… proof lanes (#231 PR 2) Adds UnitTestsAuthoringEdit to the core module (paths + tests) so the catalog target has a proof lane, rewrites the evidence manifest against the touched subsystems' required lanes (core, interaction, quick, build_policy, governed-execution incl. the canonical-json-golden fixture and packaging workflows; the independent-validation stub is listed unresolved), and clang-formats pdfauthoringedit.h.
… test targets (#231 PR 2)
The defaulted operator== makes GCC 13 instantiate the definition while QList's own equality is still forming (has_operator_equal probe), a hard error CI caught; the explicit declaration is portable and MSVC-identical.
…lpers firstLinkOnPage/linkOnPage returned a raw pointer into a temporary or local PDFAnnotationPtr, so the annotation was freed before use; glibc's freed-chunk metadata clobbers the vtable and the next dynamic_cast segfaults (MSVC survived by heap luck). The helpers now return the owning pointer and call sites downcast explicitly.
feat(quick): direct mutations through the catalog — bookmarks/links, annotations, forms/attachments/metadata (#231 PR 2)
… cannot carry Adversarial review of the #272 train (docs/reviews/2026-10-11-dev-review-272.md), findings 1-6. A named or unparsed outline destination no longer resolves to page 0, so a toggle cannot delete a hyperref bookmark and export refuses it typed; the outline rewrite guard requires a valid GoTo destination the object factory can write; the XMP merge pre-scans element and attribute occurrences, substitutes attribute-form properties, declares the namespace on replaced and appended properties and refuses an ambiguous duplicate as xmp-unreadable; attachment add/remove refuses an inline specification with the new attachment/specification-not-addressable code instead of unlisting it; form values propagate to same-named fields as PDFFormManager::setFormFieldValue does, preferring a widget-bearing match; fromString validates the hash field (the empty run stays valid: that is what an in-memory document serializes) so a corrupted hash cannot decode.
…ayer cache and the signature release Findings 7-14. composeCanvasImage draws each tile at its placed rect: the composed image's own device pixel ratio already maps viewport units to device pixels, so the previous *ratio double-counted HiDPI; extractPage refuses a copy-restricted document with PdfTool's own sentence; the cached empty text layout can no longer turn a no-text-layer refusal into an available empty selection; a refused signature-check completion releases the one-check flag when it is still the current check (a superseded completion cannot release a newer one); the annotation cap leaves 3500 of 4000 frame slots so the steering primitives always fit; the unreachable supersede branch is gone; the 18-id annotation command table is pinned by a literal list.
…ge readout Findings 9, 16-19, 21. The Quick shell answers documentMailRequested with a composed mail-client hand-off and bookmarkImportRequested/bookmarkExportRequested with the file dialogs that answer the host invokables, so no command reports a hand-off nobody performs; the soft-proof state label binds softProofSummary as the property it is; the ink-coverage readout publishes only for a succeeded job and does not outlive its revision; Copy and image extraction join the copy-permission gate actionExportDocument already used, and copySelectedText refuses with the CLI sentence; the annotations tab button gets its siblings' wrapping content item in both QML copies. Tests: the bookmark round trip asserts the custom record and reads the invocation result; screenshot-overwrite refusal and the stale-readout fence are pinned.
…cabulary gaps Findings 23-28. check_quick_localization.py and the MenuModel label agree again (actionExportDocument gets the ordinary switch arm) and the checker, its unit tests and the help-strings staleness check run whole-tree in ci.yml and check-change.py; the handler-coverage ratchet refuses to grow unless --accept-new-gaps records a deliberate gap with its reason; the identity checker scans .in/.ui/.qrc and the Wix installer template names the real LOOP artifacts; disposition and target are validated against the schema vocabulary in verify-command-catalog.py and the Linux twin; UnitTestsLoopStateVisual loads the compiled catalogs via its ctest environment; ADR-014 pins the shipped counts.
The finding set with per-item dispositions, the dismissed items (signature badge; the relative include, dismissed with build evidence), the deferred items (history re-verification on the interactive thread; the self-referential accessibility test), the verified-clean list and the change fragment with its evidence manifest.
The Quick shell policy forbids Qt.openUrlExternally in QML. The Send by E-Mail receiver added in this train called it, which failed the quick shell policy gate in CI. The host now builds the mailto URL (subject and body carry the file name and revision) and opens it through QDesktopServices. A client that does not take the message is refused with mail/client-unavailable instead of reported as handed off. The QML receivers are removed from both shells. The unit test captures the mailto URL with a URL handler, so no mail client is launched. Claude-Session: https://claude.ai/code/session_01WWpvxcKrZtceyLLgMhoZ3k
fix: apply the adversarial-review findings for the dev train promoted by #272
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promotion
unstable→stablefor the 0.2.1 patch line. Closes the operator, product-surface and trust leftovers from the 0.2.0 line that sat on 0.3.0 before the roadmap realigned, and rules out governed correction execution (that stays on 0.3.0).Scope: no tag on
stable(git describe --tagsfinds none); base4b171b07→ tipd809628d— 49 non-merge commits, 8 topic PRs merged intounstable(#262, #263, #264, #266, #267, #268, #271, #273).Canonical milestone text:
docs/github-milestones/0.2.1.md.Added
InteractionToolvocabulary; text selection and copy resolve through Core text layout, measurements stay out of the drag path, and a page without a text layer reportstext/no-text-layer(L03-13g — Measure distance, perimeter, and area on the Quick canvas #238, L03-13a — Select, copy, and capture text and images in Quick #232).docs/shell-handler-coverage.jsonplusscripts/verify-command-catalog.pyfail the catalog check when a KEEP or ABSORB action is unbound and not recorded in the ratchet (L03-13 — Restore Quick GUI coverage for the retired Widgets surfaces #231).Changed
CommandCatalogpath, per ADR-014; governed Fix keeps the planned-operation path (L03-13 — Restore Quick GUI coverage for the retired Widgets surfaces #231).menu_group.Fixed
PDFBookmarkRecordso the GCC build compiles.Internal
Refs
Issues touched by this promotion whose acceptance criteria were not verified for this body. Closing keywords act only on merge into
stable, so each stays open until its criteria are confirmed:unstable; close decision pending per-issue acceptance reviewBreaking changes
None. All eight topic fragments on
unstablerecordBreaking-Change: no.Verification
Not yet established for this promotion. Required before merge:
python scripts/agent/check-change.py --base origin/stable --build-dir build-localon headd809628d, with the result quoted here. Topic PRs carry their owncheck-changeresults on their PR pages.🤖 Generated with Claude Code