Repository navigation
feat(quick): handler-coverage gate and read-only surfaces (#231 PR 1) - #267
Merged
Merged
Conversation
#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.
Keep both sides of the overlay, editor host, and test additions: the ink coverage and signature-check finish jobs, the display-mode and soft-proof properties alongside the signature properties, and the measurement and text selection tests alongside the annotation tests. The overlay primitive emitter keeps the label and page-polygon parameters from this branch and takes the annotation selection flag from dev as a trailing parameter; the annotation call site now passes empty label and polygon values. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqo8EDq3w2nU1zekEZDoZc
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
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 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
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
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.
Epic #231 restores Quick GUI coverage for the retired Widgets surfaces in three PRs. This is PR 1: the contract-level handler-coverage gate plus the read-only and presentation surfaces (measure, select/copy/capture, soft proof and separations, settings and diagnostics, and the display half of the production colour modes). PR 2 brings the direct mutations and PR 3 the governed Fix and publication operations; both stay on this branch as their base.
The gate is
docs/shell-handler-coverage.jsonplus the handler-coverage ratchet inscripts/verify-command-catalog.py. The descriptoravailabilityflag is the handler gateCommandCatalogenforces, so the ratchet reads availability rather than string mentions: every KEEP or ABSORB action must be implemented or recorded, the recorded set must match exactly (a new unbound action fails, and so does a baseline entry kept after its handler lands), and--record-ratchetrewrites the baseline from the contract. The first run recorded 70 gaps ondevat b08e218; this branch ratchets the baseline to 51 and it can only move down. Negative-case tests inscripts/ci/test_command_catalog.pyprove each rule can fail; the check runs as its own step inci.yml's source_integrity job and as whole-tree evidence inscripts/agent/check-change.py, anddocs/LOOP_SHELL_CONTRACT.mddocuments it.The surfaces on top: Measure and text selection join the closed
InteractionToolvocabulary as their own interaction kinds, producing a revision-fencedMeasurementin production units that never becomes aDragSessionand a revision-fencedTextSelectionresolved through Core's text layout in reading order, with nine bound commands, screenshot and image extraction through the atomic writer, and atext/no-text-layerrefusal instead of an empty copy (#238, #232). The fiveactionColor*display modes are presentation-only filters over admitted surfaces, converted with Core's own converter, marked as simulations by the fidelity indicator and never reachable as production evidence; soft proof renders through a local LittleCMS proofing CMS behind its own surface identity with profile-missing and profile-invalid as visible states; plates carry show/hide/isolate state over Core's separations with a real ink-coverage readout (#235 display half, #237). The shell gains one typed settings store with confirmed reset-to-factory, the settings/render-option/diagnostics commands developer-gated, the ADR-006 bundle from Core's collector, the five KEEP render options reclassified ADVANCED with rationale, and manifest-driven menu routing (#239). The absorbedsignature-pluginandscanner-pluginproduct-surface rows keep their reviewednullfollow-ups (both have delivered replacement surfaces, which the epic's acceptance permits) so they stay in parity with the G00 source register; re-homing them would amend reviewed governance data and is left to the register owner.Validation:
check-change.py --base origin/devpassed at the head SHA — 112/112 checks acrossbuild_policy,documentation,interactionandquick, with the 24 mapped suites built and run in the worktree build, clang-tidy over every changed translation unit, and the catalog/ratchet/mirror-parity/source-integrity/architecture/product-surface checks green. The three surface workstreams each ran their focused suites green before integration and reported their evidence. One EditorHost ctest lane flaked during two earlier gate attempts; both modes were root-caused to the environment rather than the diff — a leftover recipe in the shared QStandardPathsqttestdirectory written by a concurrently running worktree session (proven by a deterministic repro: clean directory 54/54 pass, one leftover file reproduces the exact failure) and, separately, an empty-output non-zero exit with no crash report, the signature of an external process kill while another session frees build file locks; both are recorded as #265. CI runners are clean, so the hosted gate is unaffected. Limits: no native-GPU smoke (headless offscreen + software backend only), no release-profile build locally, and the pwsh/WSL-dependent CI lanes are absent on this host.Quality review: the slices reuse Core's own text layout, colour conversion, CMS and diagnostics machinery rather than inventing parallel semantics; the display filter is confined to the scene-graph upload path so it cannot leak into a surface identity; and every unfinished piece (isolated-plate pixels and the reference-separation comparison for #237, keyboard-only measurement placement for #238, and
actionRendering_Errors/actionMagnifier/actionGetSourcestaying declared for #239) is reported as a gap rather than dressed up as done.Advances #231 — the contract gate and the first surface group are in place; the epic closes when the ratchet reaches zero in PR 3.
Advances #232 — text selection, reading-order copy, capture and extraction are bound and tested, including the host-level refusal to overwrite an existing file; the screenshot write shares that same atomic writer and policy.
Advances #238 — the measure tool, production units and revision fencing are tested; keyboard-only placement of a measurement is not implemented.
Advances #237 — soft proof, plate state and the ink readout are real; isolated-plate pixels and the reference-separation comparison remain open.
Advances #239 — all four acceptance bullets are covered by tests;
actionRendering_Errors,actionMagnifierandactionGetSourcestay declared pending their layers.Advances #235 — the display colour modes are complete; bleed fixup, bitonal document creation and render-to-images belong to PR 3.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.