Skip to content

fix(validate): stop the false positives, name the right edge, warn once - #449

Merged
LeadcodeDev merged 1 commit into
mainfrom
ws-f-validator-consistency
Sep 29, 2026
Merged

LeadcodeDev merged 1 commit into
mainfrom
ws-f-validator-consistency

Conversation

@LeadcodeDev

Copy link
Copy Markdown
Owner

Closes #437. Part of #438.

Arrow and connector bounds. The geometry pass paid arrowhead padding on all
four sides whether or not a head was drawn, so a headless arrow 30 px from an edge
was reported as overflowing. The padding is conditional on
arrow_start || arrow_end now. The same function ignored a curve's implicit
control point, so a bulging arrow could leave the frame and validate clean — the
control point is folded into the bounding box, a conservative bound because a
quadratic stays inside the hull of its three points.

The overflow hint named an edge it never measured. It always said "current
right edge" on X and "current bottom edge" on Y, so a left-edge overflow at
x = -102 was reported against a right edge. It names the edge that actually
overflowed.

Gradient stop vocabulary. gradient_text's stop position accepts offset
as an alias. The two spellings had no semantic difference to justify two names,
and aliasing keeps every existing scenario working where renaming would not.

That has a hard dependency the workstream flagged and could not satisfy itself:
schema.rs's alias table needs the matching entry, or the exported schema
declares offset invalid while the parser honours it — exactly the class #162
closed. Added.

The duplicated warning. "Overlap longer than transition" printed twice at
validate and three times at render. There was only ever one eprintln!, in
v2_build_composited, reached by however many callers happened to build frame
tasks that run. Detection moves into a pure function called once from
check_off_grid_cuts, and the diagnostic leaves a planning function that had no
business emitting it.

Durations. validate printed one decimal, so 2.95 s read as "3.0s" — exactly
the figure someone sizing a voice-over would trust. Three decimals, matching
migrate, sheet and tasks.

A gap this turned up in #446's own test

The workstream predicted its alias would break
every_serde_alias_in_the_sources_is_reachable_from_the_exported_schema. It did
not — and the reason is a weakness in that test, not good luck: it checks the
alias string appears anywhere in the schema, and "offset" was already there as
a background stop's own field name.

Two tighter tests replace the assumption.
every_entry_in_the_two_tables_actually_lands_in_the_exported_schema immediately
found two inert entries I shipped in #446: ("Component", …) and
("ChildComponent", …) name definitions that no longer carry the enum, because
wrap_with_directives renames them to ComponentBase/ChildComponentBase before
the aliases are applied. The aliases were landing through the …Base entries
alone. The dead rows are removed.

Docs

text-component-parity.md and SKILL.md said, as of #446 an hour ago, that the
validator refuses offset on a gradient_text stop. That is now false, and both
are corrected in this PR rather than left to contradict the code.

Tests

Nine, each reverted and watched go red:

an_arrow_with_no_arrowhead_near_the_edge_does_not_false_positive_on_head_padding
a_curved_arrow_that_bulges_off_the_top_edge_is_caught
overflow_hint_names_the_left_edge_not_the_right_for_a_negative_x_overflow
dropped_v2_transition_warning_is_reported_exactly_once_by_off_grid_cuts
printed_duration_keeps_frame_level_precision_instead_of_rounding_to_one_decimal

Not in scope

info.rs carries the same {:.1}s display and the deeper duration-accounting
bugs of #372 items 1 and 2. #437 names the validate display only.

Five items from #437.

An arrow or connector paid arrowhead padding on all four sides whether
or not a head was drawn, so a headless arrow 30px from an edge was
reported as overflowing. The padding is now conditional on
arrow_start || arrow_end. The same function ignored a curve's implicit
control point, so a bulging arrow could leave the frame and validate
clean; the control point is folded into the bounding box, which is a
conservative bound because a quadratic stays inside the hull of its
three points.

The overflow hint always said "current right edge" on the X axis and
"current bottom edge" on Y. A left-edge overflow at x=-102 was therefore
reported against a right edge that was never measured. It names the edge
that actually overflowed now.

gradient_text's stop position accepts offset as an alias. The two
vocabularies had no semantic difference to justify two names, and
aliasing keeps every existing scenario working where renaming would not.
schema.rs's alias table gains the entry, without which the exported
schema would declare offset invalid while the parser honours it --
exactly the class #162 closed.

The "overlap longer than transition" warning printed twice at validate
and three times at render. There was only ever one eprintln!, in
v2_build_composited, reached by however many callers happened to build
frame tasks. Detection moves into a pure function called once from
check_off_grid_cuts, and the diagnostic leaves the planning function
that had no business emitting it.

validate printed durations to one decimal, so 2.95s read as "3.0s" --
exactly the figure someone sizing a voice-over would trust. Three
decimals, matching migrate, sheet and tasks.

Closes #437
@LeadcodeDev LeadcodeDev added the bug Something isn't working label Sep 29, 2026
@LeadcodeDev LeadcodeDev self-assigned this Sep 29, 2026
@LeadcodeDev
LeadcodeDev merged commit 5dd467f into main Sep 29, 2026
4 checks passed
@LeadcodeDev
LeadcodeDev deleted the ws-f-validator-consistency branch September 29, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validator and vocabulary consistency: arrow/connector bounds, overflow hints, gradient stops, duplicate warnings

1 participant