Clip behavior card labels to their bounds

This commit is contained in:
2026-09-11 10:23:36 -07:00
parent 7831abeed5
commit 4da92ab481
3 changed files with 253 additions and 18 deletions
@@ -0,0 +1,107 @@
# Lifecycle header overflow correction — 2026-09-11
Owner: Codex-ytr83r /root/windows_release_gap_review. Bounded root assignment;
source ownership approved before editing: `crates/oa-desktop/src/behavior.rs`
shared Scene box text path and existing
`crates/oa-desktop/src/behavior/scenario_lifecycle/render_tests.rs` only.
## Observed defect and diagnosis
Root exercised admitted typography-wide source on production freeze29084050,
immutable Windows GUI SHA prefix47332A6E. At1100×700/80%, receiver header card
spanned approximately x515–679 while its eighteen-W name continued to about730;
64% and subsequently100/125/156/195% also showed overflow. Reviewer inspected
`.local/lifecycle-native-ui/screenshots/wide-latin-oa-header-overflow-min-80.jpg`
and confirmed the text visibly crosses the card's right border. The Create capsule
below contains its text correctly; selection remains original occurrence110.
These are pre-correction native observations, not evidence of a corrected build.
No CJK156% observation is inferred from the interrupted later Computer Use action.
The shared Scene text loop used `short(title, (width-25)/7)` and an analogous
detail estimate with divisor6, then unbounded `Frame::fill_text`. Scalar-count
truncation cannot bound wide Latin/CJK glyphs, combining clusters or emoji. The
card is204×70 world units with title at(+12,+12), detail at(+12,+39). Both text
lines can overflow independently. Existing B4 Create text already uses a bounded
`with_clip` child frame and explicitly reapplies the scene scale.
## Applied correction
Added small `box_text_clip(rect, scale, viewport)` helper: inset10 world units
horizontally and8 vertically, transform to local drawing-frame coordinates by the
scene scale, then intersect with the actual parent viewport. Invalid scale or an
empty interior produces no text. The shared box title/detail loop uses this clip
and reapplies `label.scale(self.scale)` inside the child frame, whose WGPU transform
starts at identity. Both text draws retain their exact content/shortening rule,
positions, sizes, colors and selection behavior. No new layout engine or dependency.
Cards, outlines, message labels, lifecycle capsules/markers, insertion slots, hit
geometry, Project, source, names, history and camera state are untouched. The
shared card path also protects other Scene cards using it; it does not change
their layouts. Overflow is hard-clipped inside the existing card, so the last
visible glyph may be cut and an existing ellipsis may lie beyond the clip. This
bounded tradeoff preserves the current single-line design and exposes the full
unchanged name in Properties; pixel-measured ellipsizing is not required to prevent
the demonstrated leak.
Current Scene drawing applies scale; its outer canvas/scrollable owns scrolling.
Do not subtract `scroll_offset` again inside the clip or child frame. For the
future peer shared-canvas pan integration, transform **both** clip rectangles and
child text by the same pan+scale convention, just as for B4 Create labels. This
change deliberately does not invent a new pan convention.
## Prepared regression coverage and evidence limits
Three tests added to the existing admitted real-Scene suite:
- `real_scene_long_header_title_and_detail_keep_names_and_have_bounded_clips`:
OA/SA wide W, CJK, combining and joined-emoji names, full title/detail retention,
unchanged204×70 header and exact lifeline selection, clip containment at
scales0.05/0.5/0.512/0.64/0.8/1/1.953125/2. The existing Fixture::scene gate also
checks ordinary core/source admission, Project/SourceBundle/history immutability
and stable lifecycle geometry.
- `box_text_clip_intersects_parent_viewport_and_rejects_empty_interiors`:
partial viewport intersections on right/bottom and negative origins, disjoint
and zero viewports, invalid scales and empty padded interiors.
- `real_scene_wide_latin_header_exceeds_old_character_budget`:
actual renderer Paragraph/font/shaping defaults measure the unchanged shortened
title and detail. Both must exceed the old available width, proving this is a
real-glyph falsifier rather than another character-count assertion. This is
font/layout evidence when run, not a screenshot/pixel-render acceptance gate.
**Uncompiled and unexecuted by this worker.** No Cargo, rustfmt, compiler, tests,
native UI, Git/index or WSL actions. Root's strict workspace pass16:45:59 and
affected prior let-chain test pass16:56:53 predate this production correction.
They do not transfer acceptance to these changed bytes. Root owns scoped
format/compile/tests, strict checks and a matching GUI rebuild/native recheck.
Native toolbar factors are51.2%/100%/195.3125% plus minimum Fit; exact0.5/2 are
prepared geometry-test cases, not claimed selectable native zoom settings.
## Source readback and handoff
The interrupted private preparation completed only an ignored proposed
`.local/lifecycle-header-overflow-correction-ytr83r/behavior.rs`. Before actual
edits, both production hashes still matched the frozen inputs. Root explicitly
released the source freeze before application. No other source or prior report
was edited.
Readback confirms behavior.rs exactly matches the prepared proposal. Removing
only the three inserted tests in memory reconstructs the complete original test
file SHA256, so unrelated test bytes are preserved.
| File | Before SHA256 | Corrected SHA256 |
| --- | --- | --- |
| behavior.rs | F2FB8850480FB96F8038A4C1D855EE31E408890B1D943E7B3A9F26B5E4498445 | B47E1DF6F88282D907CD5726A03DB0BF066B60B134962A223F11842482E75946 |
| scenario_lifecycle/render_tests.rs | 2942071D768CE021CA0DCE2FE2667BBA14DE0F3FA1D4176B7A6ECDCC156B2AA9 | 13716CBD059C99D7355DB1A777241F38C713050CB554C1643E7294106D1A95D0 |
Root should inspect the two-file diff, run the three new cases together with the
existing lifecycle suite, and verify both header lines stay inside their borders
while names/selection/history remain unchanged on a new matching GUI. Include
the already admitted Unicode variants and scrolling/zoom/minimum viewport cases.
Linux remains user-paused. This is a source correction handoff, not closed native
acceptance or first-release completion.
## Root review and source freeze
Root reviewed the two-file diff and all shared card dimensions, then ran scoped rustfmt successfully. behavior.rs remains B47E1DF6F88282D907CD5726A03DB0BF066B60B134962A223F11842482E75946; formatting changes render_tests.rs to5F8410FC80C85C9DFF6A47353FA9B82FD589F098E82EB9D24FDA030AFD603652.
A separate GPT-6 Astra reviewer found no material source issue for the configured WGPU backend after checking child-frame identity/paste transforms, viewport intersection, outer scrolling, compact branch cards and empty-label activation markers. Model strings, hits and existing shortening rules remain unchanged. This is static review: the tests do not exercise the complete draw loop or prove rendered pixels. Root must compile/run the new tests and verify a matching native build before accepting the correction. No corrected native pass is claimed by this freeze.