[0.2.1] RC | Preflight & GUI Foundation - #554
Merged
Merged
Conversation
Adds pdfquick::tokens (LoopLibQuick/sources/looptokens.h/.cpp): semantic spacing and colour-role tokens with dark/light/high-contrast values, each foreground/background pair WCAG contrast-checked. Adds resolveStateVisual() (loopstatevisual.h/.cpp), the canonical finding/check presentation mapping issue #194 asks for, with a table-driven test (UnitTestsLoopStateVisual) asserting an incomplete check and an actively-waived finding never resolve to the passed treatment. Documents both in docs/LOOP_DESIGN_SYSTEM.md, including why this uses the repo's current Loop/Quick naming rather than the issue's stale pre-rebrand Pdf4QtLibGui/Loupe paths, and what remains open (component implementations land with their consuming surfaces #193, Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NxoABBuEB3mYqr8QyA6KuB
scripts/ci/check_loop_identity.py fails CI on any tracked text file containing the pre-rebrand product name outside its historical-evidence allowlist. The "Naming note" section quoted that name three times while explaining why this doc uses current naming instead of issue #194's stale paths; reword it to make the same point without the literal token. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NxoABBuEB3mYqr8QyA6KuB
Adding UnitTestsLoopStateVisual to UnitTests/CMakeLists.txt bumped the project-wide CMake target count the Phase 5 Widgets inventory tracks (its generator enumerates every target to prove widgets-linkage status, not just widgets-related ones). Regenerate docs/generated/phase5-widgets-inventory.json via scripts/generate_phase5_widgets_evidence.py --write (new target's widgets_linkage is "none", as expected) and update the test's hardcoded target count (70 -> 71) to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NxoABBuEB3mYqr8QyA6KuB
agent-fast's clang-tidy step runs on every changed C++ file regardless of module classification, but the cmake --build step that generates each test's AUTOMOC .moc file only runs for targets selected by classify()/selected_values() against agent-policy.json's module_boundaries paths. UnitTestsBudgetExhaustion was already listed in core's `tests`, but its source file, UnitTests/tst_budgetexhaustiontest.cpp, was missing from core's `paths` glob list, so a change touching only that file never classified as "core" and the target was never built before clang-tidy ran on it standalone -- producing "tst_budgetexhaustiontest.moc file not found". Surfaced by 0aa0d4c's one-line fix to that file. Add the missing path entry so the target builds first, as it does for every other core test file already listed there. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NxoABBuEB3mYqr8QyA6KuB
PDF/X-1a:2001 and PDF/X-3:2002 forbid live transparency, but standards-convert never called the existing PDFTransparencyFlattener operation (#164) -- live transparency was an unconditional, unfixable blocker even though Core already has a working flatten path that PageMaster's export pipeline uses as a separate stage. Wire PDFTransparencyFlattener::apply()/hasLiveTransparency() into PDFStandardConversion::preview()/apply(), mirroring the existing RGB-to-CMYK integration exactly: - New PDFStandardConversionSettings::flattenTransparency (default-on for X-1a/X-3, matching normalizeColor's existing default pattern; opt-in for X-4/PDF-A, which permit live transparency). - pdfx.transparency.allowed becomes a fixable preflight blocker only when flattening is requested, so unrelated fixtures without live transparency are unaffected (transparencyObjects stays 0, the rule already reports Passed). - The flatten runs before the output-intent/page-box rewrite and its report is surfaced verbatim under a new transparency_flatten report field -- a real, reported content change, never a silent approximation. - New flatten_transparency parameter on the standards-convert operation, available identically from PdfTool's repair command and PageMaster's export job (the one shared Core implementation). Also correct docs/STANDARD_CONVERSION.md's stale claim that an Editor adapter can land "after the 0.1.1 GUI gate": that gate is already complete per docs/LOOP_SHELL_CONTRACT.md, which gates product GUI work behind the still-closed S21/S22 admission contracts instead. Note that docs/REPO_MAP.md's LoopEditorPlugins/ module does not exist in the current Qt-Quick-based tree, so a future Editor adapter belongs under LoopLibInteraction/ + LoopEditor/qml/. No Qt/CMake toolchain is available in this environment, so the build and UnitTestsStandardOracle/UnitTestsConversionOracle/UnitTestsRepairOperation targets could not be run locally; clang-format, source-integrity, and architecture-catalog checks all pass. CI will provide the first real build/test signal for this change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JgoNmy614kqRiTBjiSjRJU
Works the net-new findings from the September 2026 read-only review that were reproducible against the current tree, plus three adjacent defects the review did not name. Security / privacy - PDFLogScrubber scrubs credential material (URL userinfo such as a Sentry DSN, HTTP authorization values, secret-named key/value pairs) ahead of the existing path and email passes. The bare auth-scheme pass deliberately excludes "Token" so parser diagnostics are not redacted as secrets. - loop-ocr reads a staged raster once by descriptor instead of re-resolving the path for isfile(), PIL, and easyocr in turn, closing the TOCTOU window; language codes are shape-validated before they reach easyocr's model file names; PdfTool stages the raster 0600. - Diagnostics bundles truncate plugin display fields. Fail-closed behaviour - PdfTool extraction commands record output.empty-result and accept a shared --fail-if-empty (exit 1, findings) so an empty output directory cannot pass a pipeline that gates on produced files. - writeIncremental reports whether it appended or only byte-copied; damaged documents now carry a source digest, so its "file changed underneath us" guard is no longer silently disabled for permissively recovered documents. Bounds on attacker-controlled shapes - Damaged-document recovery bounds its dense object table by objects recovered, not by the highest declared object number. - PDFNameTreeLoader terminates cyclic Kids chains and caps depth, entry count, and key length (net-new: the cycle was unbounded recursion). - Structure-tree parsing bounds recursion depth on long acyclic chains. - PDFJBIG2Bitmap::paint validates grown dimensions on its expandY path, the one path that escaped the constructor's dimension check (net-new). Ergonomics - isPathContained no longer rejects a planned output whose target directory does not exist yet, keeping the stricter symlinked-parent rule for the file side. - makeUniqueFileName probes 128 sequential names, then random ones. - OCR option defaults are defined once and shared by capability discovery and the command-line parser. Not built or run here: this environment has no Qt, so the C++ changes are unverified by compilation. The Python sidecar tests pass and the new scrubber patterns were validated against a reference implementation of the same passes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FDJQDFR5ctoKDJbp7LG4GS
Whole-file clang-format across LoopLibCore/PdfTool/UnitTests sources to clear format drift flagged by agent-fast. Add moc-generated autogen include dirs to UnitTests target so Qt meta-object headers resolve. Map agent-policy tidy gates to the three active test suites.
Add canonical milestone text for 0.2.1 (patch on the 0.2.0 line), register GitHub milestone 17 in the sync manifest, and update living-sequence references across milestone docs and the 0.5.0–0.10.0 roadmap extension. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Replace legacy product tokens in milestone issue summaries, rename the budget-exhaustion corpus schema kind to loop, and fix workflow working-directory typos left from the Loupe-to-Loop rebrand. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Manual .moc includes are generated at build time, so clang-tidy cannot analyze those sources during agent-fast. Exclude them from tidy while keeping format checks. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
…#144) Add pdf::PDFBlockingThreadGuard, a runtime thread-affinity check a blocking service adapter opens with so it refuses to run on the registered interactive (canvas) thread instead of silently stalling pointer and frame handling. Wire it into PreflightEngine::run(), the one blocking implementation already reached through PDFJobScheduler, and register EditorHost's owning thread as the interactive thread at construction. Add PDFJobKind to PDFJobTraceEvent so job traces identify async work by type, and document the interactive-thread boundary (what pointer/frame callbacks may do directly vs. what must go through a submitted job) in docs/JOB_SCHEDULER.md. Wiring an actual UI trigger for interactive preflight runs, and correlating PDFJobTraceEvent timing against InteractionTraceRecorder's slow-frame attribution, remain open follow-up work for #144. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xnr9TZYfGr1nMgBeh16CSb
Add pdfinteraction::evaluateTraceContracts() and its TraceContract/TracePhase enums (LoopLibInteraction/sources/interactiontracecontract.h/.cpp): the fixed-order pass/fail evaluator issue #146 AC7 asks for. Given an ordered QList<TraceContractCheck>, it returns the first unsatisfied contract and the phase responsible, matching scripts/ci/check_interaction_traces.py's CONTRACTS/PHASES tuples and docs/schemas/interaction-trace-report.schema.json exactly, so a future harness that supplies the nine checks in order gets AC7 for free. phaseForStage() is docs/INTERACTION_CONTRACT.md's TraceStage-to-phase attribution table given a type. The evaluator takes an already-assembled checklist rather than an InteractionTraceRecorder or a live replay, so it is fully testable with synthetic checks -- no InteractionController, no scheduler, no hit-test dispatch -- and is covered by the new UnitTestsInteractionTraceContract target. The prior gh-146 work (scenario/report schemas, the nine-scenario corpus, and check_interaction_traces.py) validates the corpus as data but has no test binary to produce a run; this evaluator is the piece that decides a run's verdict once one exists. Replaying a scenario through InteractionController, applying its cost model, and assembling a full report run remain open, as UnitTestsInteractionTraces/UnitTestsInteractionTracesPresent in docs/INTERACTION_CONTRACT.md's two-lanes table. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xnr9TZYfGr1nMgBeh16CSb
…readGuard docs/generated/phase5-widgets-inventory.json went stale when UnitTestsBlockingThreadGuard landed (issue #144 commit): it's a target directly in UnitTests/CMakeLists.txt, which scripts/generate_phase5_widgets_evidence.py scans, but the catalog was never regenerated for it. CI's policy job caught the drift -- test_verify_phase5_widgets_contract.py's crlf-currency check and its hardcoded target count (70) both went red against the actual count (71). Regenerate via scripts/generate_phase5_widgets_evidence.py --write and bump the test's hardcoded count to match. (scripts/generate-architecture-catalogs.py's separate architecture-catalog.json was already regenerated for this target in the #144 commit; this is the sibling widgets-surface catalog that step didn't cover.) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xnr9TZYfGr1nMgBeh16CSb
Rename leftover working-directory: loupe to loop in reusable Linux and Windows workflows so agent-fast/build can run generate_corpus.py --check. Rename schema_kind from loupe-processing-budget-exhaustion-corpus to loop-processing-budget-exhaustion-corpus in the corpus generator, test, and manifest so check_loop_identity passes. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
The agent-fast build proof never built the blocking-thread-guard test target because it was absent from the core module's test list, so its AUTOMOC .moc file was never generated and clang-tidy failed on tst_blockingthreadguardtest.cpp. Registering the target lets check-change.py build it (and generate the moc) before static analysis.
Defer MSI removal until after LGPL relink evidence is collected and normalize usr\bin install layout in run_qt_relink_test.ps1. Co-authored-by: Cursor <cursoragent@cursor.com>
Route GitHub Actions context through env vars, add Dependabot cooldown, and validate GitHub API slugs before urllib requests. PDF-standard MD5 usage in pdfsecurityhandler.cpp is intentionally unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
…ues (#194) Continue PR #525 on current origin/dev. Shared pdfquick::tokens cover spacing, typography, focus geometry, and colour roles; resolveStateVisual() is the canonical finding/check mapping. Incomplete and waived states never resolve as passed, and each state carries a unique icon plus accessible name. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Qt::red against white is only ~4.0:1. Use the light-theme fill (#B91C1C) so a destructive button label still meets WCAG text contrast in high contrast. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Drop restated enum notes, unused includes, and CMake/doc padding. Mapping invariants stay in tests and LOOP_DESIGN_SYSTEM.md. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Keep both UnitTests/tst_jbig2decodertest.cpp (PR 519) and UnitTests/tst_lifecycletest.cpp (dev) in the core module boundary paths. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Keep 0.2.1 in the living release train while adopting dev's consolidated 0.5.0-0.8.0 planned-train wording and retired-title note. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
…tract UnitTestsDocumentSearch::searchReportsIncompleteWhenOperationBudgetExhausted asserted that a budget-exhausted search is still admitted. dev's QuickDocumentModelTest::exhaustedSearchReturnsAnIncompleteResult asserts the opposite, and pdf::searchDocumentText returns before it evaluates admission when the budget stops the search, so this branch's expectation is the one that has to move. The slot keeps what this branch added: the machine-readable budgetExceeded flag, the not-completed assertion, and the empty-match assertion.
findingNavigationMovesCanvasToTheFindingPage asserts that selecting a finding moves the canvas to its page, but the check never sized the viewport. With no viewport size placedPageRect() has no valid rect, so the page cannot be revealed and currentPage() stays -1 whatever the navigation code does. Every sibling check in this file calls setViewportGeometry(); this one did not. The check has been red since it was added in 11d0dea, whose agent-fast never built the quick targets: the LoopLibCore compile error in that commit failed the lane before the tests could run, so this row was never exercised. Reproduced and verified locally against the open PR branches' merge, which carry the same check: 13 passed / 1 failed before, 13 passed / 0 failed after. The product navigation code is unchanged.
…196-170-operator-loop
The twelve overprint render fixtures were built with every page box equal, so they had no bleed at all and loop-default.json's 9pt check failed them: the corpus rows that preflight them could never pass, which is why they sat behind "pending": true with no snapshot. The trim box is now inset 10pt, which gives BleedBox (still unset, falling back to MediaBox) a 10pt margin over the trim. Nothing else moves: the media box and every mark keep their coordinates, so the committed render baselines still hold and no mark gains or loses coverage. Verified locally against the corpus harness and the render suite: - UnitTestsPreflightCorpus: 11 of the 12 overprint rows now report pass=true/exit 0 (all twelve failed the bleed check before). - UnitTestsOverprintRender: 15 passed / 0 failed with the committed 128x128 baselines unchanged. overprint-multiply-on still reports "Overprint with Multiply blend mode uses a fallback; only Normal is exact" (exit 8, verdict incomplete), so its row stays unresolved: that is the renderer's fidelity classification in pdftransparencyrenderer.cpp, not a fixture defect. The regenerated fixtures carry 0.2.0-alpha in their producer header while the other twenty-odd fixtures still carry 0.1.0; regenerating the whole set is a separate, cosmetic pass.
With the fixtures carrying real bleed, eleven of the twelve overprint rows preflight as the manifest says they should (pass=true, no findings), so their "pending" flags come off and their reports are pinned as snapshots. The suite therefore stops failing on rows that were only waiting for the fixture fix. Rows still unresolved, and why, so the next pass does not have to rediscover it: - overprint-multiply-on: the renderer reports its Multiply blend as an approximate fallback (exit 8, verdict incomplete), so its recorded pass=true does not hold yet. Fixture is fine; the gap is the fidelity classification. - malformed-not-pdf: the harness requires data.report, which an unreadable input never produces, so an input-error row needs its own comparison mode. - thin-parts-fill, ai-art-* (4), transparency-* (6): no fixture exists. The generator has no builder for any of these names. Verified locally against the corpus harness: 90 passed / 26 failed rows, down from 68 / 48; the 26 are exactly those three groups.
…196-170-operator-loop
Remove const from compressed QByteArray and qMove it into PDFStream constructor, matching the pattern used elsewhere in pdfrgbtocmykfixup.cpp. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
…ation (#566) <!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Summary Closes the 0.2.1 release-gate gaps for GitHub #520 and #241. ### #520 — fresh processing budget per search - `searchDocumentText()` now allocates an operation-scoped `PDFProcessingBudget` instead of reusing the session budget whose elapsed timer starts at session construction. - Budget exhaustion is surfaced as `PDFDocumentSearchResult::complete=false` / `budgetExceeded=true`; `QuickDocumentModel::search()` returns `false` without letting `PDFBudgetExceededException` escape to QML. - Adds `UnitTestsDocumentSearch` regression coverage and `scripts/ci/check_search_budget_gate.py`. ### #241 — independent validation release gate - Adds `scripts/ci/check_independent_validation_gate.py` to keep the oracle lane reviewable: conversion triad manifests, `run_independent_validators.py`, `UnitTestsStandardOracle` / `UnitTestsConversionOracle`, and self-certification source markers. - Wires both guards into `ci.yml` `source_integrity` and `scripts/agent/check-change.py`. ## Verification - `python3 scripts/ci/check_search_budget_gate.py` — pass - `python3 scripts/ci/check_independent_validation_gate.py` — pass - `ctest -R '^UnitTestsDocumentSearch$'` — pass - `python3 scripts/agent/check-change.py --base origin/dev` — focused tests 34/34 pass; clang-tidy exits non-zero on touched TUs due to pre-existing `'utility' file not found` diagnostic in this environment (not introduced by this diff) ## Plan See coordinator plan: `/cursor/stores/self/internal/issue-520-241-release-gates-plan.md` Fixes #520 Refs #241 <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-414bc936-d3b7-509a-86c5-5bf256827962?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-414bc936-d3b7-509a-86c5-5bf256827962&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/studio-berry/codesmith/loop/pr/566"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1791864821&installation_model_id=435800&pr_number=566&repository=studio-berry%2Floop&return_to=https%3A%2F%2Fgithub.com%2Fstudio-berry%2Floop%2Fpull%2F566&signature=bec110427aa6391d5e2b976b65459615377aef9982e2758dcf197848e81d2552"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer -->
- Add transparency, ai-art, and thin-parts-fill PDF fixtures - Unpend malformed-not-pdf and overprint-multiply-on manifest rows - Generate thin-parts-fill via LoopGenerateFixtures - Handle PdfTool input-error envelopes in corpus runner - Add/update golden snapshots for promoted fixtures Co-authored-by: michael berry <mberrys@users.noreply.github.com>
- Add transparency, ai-art, and thin-parts-fill PDF fixtures - Unpend malformed-not-pdf and overprint-multiply-on manifest rows - Generate thin-parts-fill via LoopGenerateFixtures - Handle PdfTool input-error envelopes in corpus runner - Add/update golden snapshots for promoted fixtures
mberrys
removed this pull request from stack #567
September 13, 2026 21:22
<!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/studio-berry/codesmith/loop/pr/553"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1791600580&installation_model_id=435800&pr_number=553&repository=studio-berry%2Floop&return_to=https%3A%2F%2Fgithub.com%2Fstudio-berry%2Floop%2Fpull%2F553&signature=ab98d916d41408e5c1fb169c637fd5aac9ec72b93e39eaa53421abfcc2d7f7dc"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer -->
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
#196) - Wire canvas overlay clicks through selectFinding for full navigation - Add selectNextFinding/selectPreviousFinding with Alt+Up/Down shortcuts - Invalidate FindingCanvasNavigator on revision sync - Sync PreflightPane list highlight to selectedFindingId - Populate evidenceTargets from finding bbox in navigation requests - Add shell keyboard and inspector dispatch tests for finding navigation Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Move adjacent-finding selection into PreflightFindingsModel so EditorHost does not aggregate finding counts. Enable Alt+Up/Down shortcuts from Core preflightStateName and mirror Main.qml in the accessibility smoke target. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> Closes the documentation scope of GitHub #235 / Linear MB-463 for the **0.2.1** architecture-truth gate. PR #255 (2026-08-10) introduced ADR verification headers, generated architecture catalogs, and the `Documentation truth` CI workflow. This follow-up re-verifies that narrative against **current `dev`** at `e65cdd19` after DocumentContext revision authority (#236) and subsequent preflight/session work. ## Changes - **ADR-001** — align with revision-keyed caches, optional `PDFDocumentContext`, admission modes, byte-bounded eviction, and factory API - **ADR-002** — add `thin-parts`, graph-backed checks, and pointers to generated check catalogs - **All ADRs** — refresh `Last-verified` to `2026-09-13 @ e65cdd1…` - **`docs/adr/README.md`** — new ADR index with status table and catalog regeneration instructions - **`docs/architecture-source-of-truth.md`** — cross-link revision authority and `preflight-check-catalog.json` - **`docs/REPO_MAP.md`** — link ADR index in layout table - **`loop-preflight/README.md`** — clarify v2 examples vs v3 engine output ## Verification - `python3 scripts/generate-architecture-catalogs.py --check` — pass - `python3 scripts/agent/check-change.py --base origin/dev` — pass (includes mapped preflight focused tests) No protected contract or schema changes. Refs #235 <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-f35ce71d-cccd-5600-a2ca-25dac77ee16d?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-f35ce71d-cccd-5600-a2ca-25dac77ee16d&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/studio-berry/codesmith/loop/pr/565"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1791864553&installation_model_id=435800&pr_number=565&repository=studio-berry%2Floop&return_to=https%3A%2F%2Fgithub.com%2Fstudio-berry%2Floop%2Fpull%2F565&signature=a50e96230032f93f6325b2a26bec45140ef068785ea2a39a5697946431046be1"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer -->
## Summary Implements the Qt Quick operator loop across shell information architecture, first-class revision-bound preflight, report-backed Prepress Inspector, finding-to-canvas navigation, and bounded GUI/E2E verification. ## Issue linkage - Related to #193 - Related to #195 - Related to #127 - Related to #196 - Related to #170 ## Verification - Focused CTest: 9/9 passed. - Product operator-loop: 8/8 passed. - Quick accessibility smoke: 3/3 passed on native and software paths. - Repository gate: source, architecture, policy, preflight-truth, mirror-parity, formatting, builds, clang-tidy, and 29/29 policy-selected tests passed with the configured environment. No issues are auto-closed by this PR. <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/studio-berry/codesmith/loop/pr/564"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1791862718&installation_model_id=435800&pr_number=564&repository=studio-berry%2Floop&return_to=https%3A%2F%2Fgithub.com%2Fstudio-berry%2Floop%2Fpull%2F564&signature=07ad839c084425c0ba71236010ce4f16fdbad9e5842e8c5e44fe3acc388b79b9"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer -->
Fix whitespace alignment in the nested ternary that maps preflight verdict states to exit codes. Unblocks agent-fast on dev and RC PR #554. Co-authored-by: michael berry <mberrys@users.noreply.github.com>
7 tasks
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## What changed Agent-fast on `dev` failed with `-Wclang-format-violations` on lines 298–299 of `UnitTests/tst_preflightcorpus.cpp` (nested ternary whitespace). This PR applies clang-format to that file only, unblocking RC PR #554. ## Proof - [x] `clang-format --dry-run --Werror UnitTests/tst_preflightcorpus.cpp` passes locally - [x] One `changes/cursor-fix-preflightcorpus-format-6547.md` fragment added - [ ] Changed behaviour has a test that fails without the change — N/A (format-only) - [ ] Protected-path or contract change — none ## Internal logic (touched behavior-bearing code) Format-only change; no logic touched. Anti-slop summary: Whitespace alignment only; no comments or logic changed. ## Security and rollback - [x] No security impact - Rollback: revert this commit ## Docs - [x] none needed — format-only fix ## Self-review (BSP-002 §4.3) - [x] Reviewed diff; format-only whitespace in ternary chain <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-ecb73197-e4af-511c-8e56-122ec4c8b371?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-ecb73197-e4af-511c-8e56-122ec4c8b371&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/studio-berry/codesmith/loop/pr/571"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1791933972&installation_model_id=435800&pr_number=571&repository=studio-berry%2Floop&return_to=https%3A%2F%2Fgithub.com%2Fstudio-berry%2Floop%2Fpull%2F571&signature=0fa64747af7a597566091c8ef76c5067c90f5578b7788d889b0fa4e6b5d1c284"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer -->
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.
No description provided.