Part of #102 — wave 1.
Mini-spec
Goal: make the geometry validator trustworthy — a non-destructive --fix, no false negatives on parent overflow, no blind spot on transform/camera, and honest animated sampling.
Invariants
--fix never writes a property absent from CssStyle. A file it rewrites must re-validate at least as clean as before, and must never lose a component.
- A node clipped by an ancestor whose
overflow is not visible is never reported as a viewport overflow.
- Content larger than its own content box is reported even when it stays inside the viewport.
- A violation path resolves to the same JSON node the validator measured, even when a sibling failed to deserialize.
Out of scope: schema changes (L4), font loading (L4), component-internal measurement (L5), the legibility floor (wave 2).
Acceptance
C1 — on an unwrappable_text_overflow, --fix removes white-space: nowrap instead of adding wrap: true; the remediation hints stop naming wrap and font_size.
H3 — with a deliberately invalid child at index 0, --fix patches the correct sibling.
H4 — a shape fully inside an overflow: hidden card validates clean; a text wider than its overflow: visible card is reported.
H7 — 420px type inside a full-frame overflow: hidden plane validates clean.
H6 — --strict-anim no longer discards t=0 through the opacity guard, reuses the renderer's effective_effects / resolve_props_for_effects rather than a divergent fork, and samples proportionally to scene duration.
H5 (partial) — static css.transform and scene.camera are folded into the bbox computation.
- Regression tests exist for each of the above (the module currently has 5 tests and none cover
apply_fixes or --strict-anim).
Files: crates/rustmotion-cli/src/commands/geometry.rs, crates/rustmotion-cli/src/commands/validate.rs
Verify
rtk cargo test -p rustmotion-cli
rtk cargo build --release
for f in examples/*.json; do ./target/release/rustmotion validate -f "$f"; done
Part of #102 — wave 1.
Mini-spec
Goal: make the geometry validator trustworthy — a non-destructive
--fix, no false negatives on parent overflow, no blind spot ontransform/camera, and honest animated sampling.Invariants
--fixnever writes a property absent fromCssStyle. A file it rewrites must re-validate at least as clean as before, and must never lose a component.overflowis notvisibleis never reported as a viewport overflow.Out of scope: schema changes (L4), font loading (L4), component-internal measurement (L5), the legibility floor (wave 2).
Acceptance
C1— on anunwrappable_text_overflow,--fixremoveswhite-space: nowrapinstead of addingwrap: true; the remediation hints stop namingwrapandfont_size.H3— with a deliberately invalid child at index 0,--fixpatches the correct sibling.H4— a shape fully inside anoverflow: hiddencard validates clean; a text wider than itsoverflow: visiblecard is reported.H7— 420px type inside a full-frameoverflow: hiddenplane validates clean.H6—--strict-animno longer discardst=0through the opacity guard, reuses the renderer'seffective_effects/resolve_props_for_effectsrather than a divergent fork, and samples proportionally to scene duration.H5 (partial)— staticcss.transformandscene.cameraare folded into the bbox computation.apply_fixesor--strict-anim).Files:
crates/rustmotion-cli/src/commands/geometry.rs,crates/rustmotion-cli/src/commands/validate.rsVerify