Preserve raw include diagnostic provenance and derive bands from the existing shaped editor. Retain deferred tooltip paragraphs through rendering. Include source, regression, failure and native-trial evidence; corrected native acceptance remains pending.
61 lines
10 KiB
Markdown
61 lines
10 KiB
Markdown
# Integrated annotation wrapper — independent static review
|
||
|
||
Reviewed frozen, untested integration in `C:/ar-text-9e8r6t` by Codex-9e8r6t `/root/publication_review`, 2026-09-13. No builds, source edits, GUI or network. No stale-publication, input-capture or editor-state mutation blocker found in the reviewed integration. Tooltip presentation and actual wrapper behavior still need the discriminating tests below; the isolated accessor result does not establish those outcomes.
|
||
|
||
## Remaining findings and checks
|
||
|
||
**Tooltip footer has no measured-height guarantee.** source_annotations/widget.rs:296 and :381–399 reserve a fixed 26 logical pixels for a WordOrGlyph-wrapped footer, while draw_details admits effective clip widths down to 100 pixels. At narrow admitted clips the full-details route can require more rows than that fixed space; unlike the body, its shaping height is not measured. Test the actual shaped footer at the minimum reachable application allocation and narrower admitted ancestor clips. If it exceeds the budget, use measured footer height or a shorter independently readable route/count, subtracting that height from the body budget. This is a concrete component geometry risk, not a claim that the actual native minimum window has already failed. No glyph widths were inferred from character counts.
|
||
|
||
**Overlap summary differs from the written count policy.** :304 admits at most four diagnostics, but the shortened footer at :373–378 states total `N problems here`; the rendering contract says bounded display states the remaining count. With five or more hits, the footer does not explicitly state omitted diagnostics, and body clipping may hide some admitted entries too. Choose explicit wording/count semantics before claiming the contract is met (for example distinguish total at the source location from omitted preview entries, with the full-details route). This is presentation precision, not lost diagnostic authority: all primary diagnostics remain in Problems. Related locations are represented by their count and route to Problems, not full related text in the painted preview; retain that scope in user-facing claims.
|
||
|
||
The paragraph is limited to four entries and 1,000 characters per entry, but `format!` first clones the entire original code/message before truncation (:311–319). Thus bounded mounted text does not prove bounded string-copy cost for unusually large diagnostics. Measure realistic/admitted long messages during the planned responsiveness check before making cost claims; no additional cache or rendering abstraction is justified solely by this static observation.
|
||
|
||
## Authority, cache and stationary-pointer behavior
|
||
|
||
App::source_annotation_snapshot (app/text_workspace.rs:387–404) requires the diagnostic publication's workspace/revision key to match source_key and requires active Buffer.text to equal source_snapshot. It supplies the active logical path and publication generation. It deliberately does not depend on Problems visibility or visit, so hiding the drawer retains current editor markings. Source file A–B–A changes the path and normally the source Arc; the cache cannot reuse a different path's index.
|
||
|
||
The wrapper cache (:159–186) contains only Index and immutable source identity, keyed by publication ID, path and Arc pointer. A fresh publication rebuilds even for identical source bytes; None clears the cache. All production assignments found for source_diagnostics go through publish_source_diagnostics, which rotates publication generation. Ordinal lookup is therefore valid under the supplied Snapshot contract; the widget is not an admission boundary for manually fabricated same-ID/different-diagnostic snapshots. Buffer-to-source run equality is additional defense, not a replacement for App provenance. The snapshot does not rescan Content.text; correctness also relies on the existing App editor/snapshot synchronization and actual-run readback, as intended.
|
||
|
||
Bands and hits are recomputed after the actual child draw, with no retained hover target, delayed message or old hitbox cache. A stationary pointer therefore uses the source publication and laid-out editor of that frame. Empty/obsolete snapshots draw no annotations. Arc changes may cause an unnecessary index rebuild but cannot silently relabel an old index current.
|
||
|
||
## Tree, input, rendering and modality
|
||
|
||
Decorations is permanently installed between the actual TextEditor and the existing sensor in views/text_workspace.rs:56–96. The same `EDITOR_PADDING = 16` configures both editor and decoration origin/inner clip. It does not insert/remove a widget based on diagnostic availability. State owns a read-only cache; its sole child Tree is diffed, not reset on publication changes. Layout, size, operate, update, mouse interaction and overlay all delegate to that child with the same child Tree/layout.
|
||
|
||
CursorMoved/CursorLeft request redraw without capture or message publication (:124–131), addressing the earlier unchanged-status hover issue. Stock child event handling remains intact. The existing outer raw-input observer does not advance its interaction clock for these motion/leave events. Geometry reads do not call perform, move_to, Content reconstruction, or focus operations. Selected-byte/focus preservation still requires mounted tests, particularly after adding this extra permanent Tree level.
|
||
|
||
Child draw precedes accessor access (:152–192), so ArcadiaHighlighter has already run; the Content borrow ends before annotation/tooltip renderer calls. Inner bounds are intersected with the supplied viewport. One balanced renderer layer clips both underlines and tooltip. The wrapper makes no extra scroll/DPI transform and adds no interactive overlay. Cached RefCell borrowing does not span a child update or reentrant Content access in this implementation.
|
||
|
||
Warnings draw first and errors afterward; the stable sort preserves publication ordering within severity. Hover deduplicates diagnostic ordinals and orders Error before Warning, then publication ordinal. It uses current clipped bands and cursor.position_over(clip), not snapping editor hit-testing. source_navigation_available disables hover for Text/model menus, rename, busy/pending/file/delete/workflow/hosted/architecture/behavior surfaces; underlying markings may remain visible, which is distinct from hover admission. Root Popup/hosted overlay ordering and delegated cursor unavailability are retained. The existing route label is actually Actions → Source problems.
|
||
|
||
## Prior anchor findings
|
||
|
||
The prior missing-wrap-space and interior-cluster findings are no longer the same implementation. source_annotations.rs:165–218 now uses actual paragraph layout plus nonempty glyph-slice identity, logical maximum glyph end and next run minimum start; exact following-run start remains following-owned. It applies the proportional grapheme-advance heuristic with RTL direction, and the contract explicitly calls this a caret affordance. Empty runs return before pointer-based run identity, avoiding shared empty-slice identity ambiguity. The new actual-layout gap test requires a real omitted separator and verifies that clipping out the preceding run does not relocate its marker.
|
||
|
||
Remaining evidence boundaries: new layout tests cover RTL **nonempty** bands and a plain LTR gap, not a mixed-bidi wrap gap or empty interior ligature. Add a real multi-grapheme ligature fixture and a mixed-direction wrap-gap case before broadly claiming those anchor cases. Equal-end multi-glyph clusters should be tested when choosing the logical trailing edge; a geometry policy must not assume arbitrary vector order equals logical order. This is not a claim that a tested fixture currently fails.
|
||
|
||
## Bounded next evaluator
|
||
|
||
Mount the actual Decorations + sensor + highlighted editor and retain one tree. Record fill_editor, underline quads, tooltip paragraph/clip and Shell output. Exercise publication Some→None→new Some under a stationary pointer; active path A→B→A; current-source edit and Undo; Problems hide; and each higher menu/modal gate. Assert old messages/bands vanish and exact selected bytes, focus, scroll, model/history and source interaction clock remain unchanged for passive hover. Move between diagnostics without changing stock hover status and require redraw with no additional application messages.
|
||
|
||
Use five overlapping Error/Warning diagnostics, long Unicode code/message text, narrow effective clips and partially visible runs. Verify actual glyph visibility of the severity/count/full-details route, body shortening indication, deterministic overlap order, no painted material outside the clip and blank-space hover misses. These checks should fail an intentionally stale snapshot or insufficient footer-height control. Parent owns compilation and subsequent native checks; no runtime pass is claimed here.
|
||
|
||
## Reviewed hashes
|
||
|
||
| File | SHA-256 |
|
||
| --- | --- |
|
||
| crates/oa-desktop/src/source_annotations/widget.rs | `8315c8b39d7b9c59815e8431218599a4db7efb30011d96ef2bf30dd495f49f3d` |
|
||
| crates/oa-desktop/src/source_annotations.rs | `3b51f08209ce794e1d5c5418156a7921467a3ea02fa3cedd7157af6df7634655` |
|
||
| crates/oa-desktop/src/source_annotations/layout_tests.rs | `1e62212ffbe414e21151690a7d8d1910920aa75b823dc51967fb76215bb03800` |
|
||
| crates/oa-desktop/src/app/text_workspace.rs | `0fee2e071ddcda78ae986724bcc9278e95e82c25dfb61d35c613ea7c7ee24575` |
|
||
| crates/oa-desktop/src/views/text_workspace.rs | `93b728e2586c98b2db165836d665f3756d4d62e16f3b0d5a4ddc113a5f527ebd` |
|
||
| crates/oa-desktop/src/app/source_symbols.rs | `d81914a553114d85452d973a1edb175843d27154b3f9b9fc4cbc5049d423abe4` |
|
||
| crates/oa-desktop/src/app.rs | `8920616602bb23efc68f23fc2a0765bc28bdcd2599f63157cfc1481b5764397d` |
|
||
| Cargo.toml | `66d401d9f7629f1f6d174ae41b7f9203c9ce3a76d69abfc4381227dbdec12eae` |
|
||
| Cargo.lock | `cd82f2d61df558f4f8121a4dacee6e17f31954947328d35a2a0c194f4ca71323` |
|
||
| crates/oa-desktop/Cargo.toml | `e4fc5d2c14d9aa84ec493d0c6bef47a1046b4929ca502e4bd096c27d4fe22587` |
|
||
| crates/vendor/iced_widget/src/text_editor.rs | `70e2b5fa29b38ceb9b7688982712647bbb60b751681bfb6c3ca6bcacb51a08e1` |
|
||
| harness/text-diagnostic-rendering-contract-20260913.md | `4d32d4de2a16b474adfbe09bf99e60496bcc2225503e052f3ac85dce92474414` |
|
||
|
||
The root Cargo patch points to the excluded local iced_widget crate, and its text_editor bytes equal the successful isolated accessor probe. This review does not repeat full vendor/license/package verification or claim completed production gates.
|