- makepad_ports_deep_assessment.md: architecture/design/performance/bugs/security/quality, scored 5.4/10 with file:line evidence; key findings: unpinned dev checkout (S1), commit-on-down + zero animators (D1/D2), undo deep-copies scene (P1), god-router + full chrome resync (A2/A3), copy-coupled UI tests (B3), test-shaped product (A4) - plans/ROADMAP.md: Phases 0-5 mapping findings to plans 000-005 + engine hardening, tranche discipline per phase
6 KiB
Roadmap — phased improvement of the makepad-ports codebase
Companion to makepad_ports_deep_assessment.md (findings A*/D*/P*/B*/S*/Q*) and the
self-contained plans 000–005. Each phase ends as a tested tranche: full test matrix green,
git fetch reconcile, then push. No phase starts on top of an unpushed predecessor.
Phase 0 Phase 1 Phase 2 Phase 3 Phase 4 Phase 5
Trust the build Foundations Interaction Motion Visual Engine & test
& measure ───► craft crate ─► correctness ───► adoption ───► polish ───► hardening
(S1,S2,Q3,Q5) (plan 000) (plan 001, D3) (plans 002-004) (plan 005) (A2,A3,P1-P5,B1-B4)
Phase 0 — Trust the build, measure the baseline (no product code changes)
The gate everything else passes through. You cannot claim 140-green while the thing under test is an unpinned branch tip (S1).
- Pin upstream:
setup_makepad.shchecks outb41e740explicitly (git fetch --depth 1 origin b41e740 && git checkout b41e740);git apply --checkfailure aborts loudly. Pin the Rust toolchain (--default-toolchain 1.98.0). (S1, S2) - Coverage harness (this tranche): temp-env
cargo-llvm-cov+llvm-tools-previewin/var/tmp(ephemeral, wiped with the sandbox — nothing pollutes the repo); engine tests (--lib --test integration, all three crates) and controller/UI tests (MAKEPAD=headless --test ui) instrumented; upstream makepad code and unreachable platform startup (main.rs,lib.rsregistration glue) excluded via--ignore-filename-regex; summary committed todocs/coverage/COVERAGE.md; uncovered model branches get unit tests in the same tranche; artifacts (.profraw, cov target dir, tool binaries) cleaned after. - CI-as-script:
ci.sh= fmt check + clippy (-D warnings, allowlist documented) + the three-layer test matrix; README states it as the pre-push contract. (Q3) - Token rotation on gitdab; pushes via credential helper. (S4)
- Vendor policy one-liner in
skills/README.md:vendor/is data, never doctrine. (S3)
Exit: pinned reproducible build, measured coverage with a committed report, ci.sh green.
Phase 1 — Foundations (plan 000)
The shared craft crate: easing/duration/color tokens on the mod object, Pressable,
CraftToast, pure motion.rs (project/rubberband/settle) with unit tests. Kills the
triplication channel (A1) before behavior work multiplies it further.
Exit: four crates build; tokens reachable from all apps; baseline + new units green.
Phase 2 — Interaction correctness (plan 001 + D3 minimum)
- Press contract everywhere: feedback on down (0.96 snap-in), commit on up-if-over, tap-cancel; documented act-on-down exceptions only (koboyo drag-arming tools, scrims). Clears every HIGH in the craft audit.
- A11y minimum riding the same migration: since every tappable becomes a
Pressable, give it focusable + Enter/Space activation + a visible focus state in the same widget — one fix, forty call sites, D3 mostly closed for free. - New UI tests: tap-cancel per crate; keyboard activation smoke test.
Exit: grep finger_down(actions) returns only documented exceptions; matrix + new tests green.
Phase 3 — Motion adoption (plans 002, 003, 004)
Order: 002 (toast, all crates — smallest, proves the enter/exit pattern) → 003 (insurance sheet settle: projection, velocity handoff, rubber-band, multi-touch guard fixing B1, grab-mid-settle) → 004 (koboyo drawer/popovers origin-aware + animated camera-fit; fixes B4 focus-before-visible). 003 and 004 may run in parallel — disjoint crates.
Exit: zero set_visible pops for toasts/drawer/popovers; sheet settles with velocity;
all restraint cases (canvas 1:1, PageFlip) untouched; matrix green.
Phase 4 — Visual & token polish (plan 005)
Hex → semantic tokens; concentric radius pass with measured paddings (closes B5); emoji → drawn
icons with state recoloring; tabular figures; … not .... DSL-only, zero redesign — today's
rendered pixels reproduced from tokens. UI-test locators migrate from copy strings to ids as
each screen is touched (B3 partial).
Exit: hex grep clean outside model-driven values; radius table in PR; matrix green.
Phase 5 — Engine & test hardening (the assessment's structural debt)
- Router: replace
handle_actionsif-chains with a dispatch table (&[(LiveId, Msg)]→fn update(flow, Msg) -> Fx), one per crate; exhaustive, testable. (A2) - Dirty-flag chrome:
refresh_chrometakes theFx/diff of what changed; full resync only on screen change. Prerequisite for animations not being stomped. (A3, P3) - Undo rework: command-pattern deltas (or
Arc<[Element]>structural snapshots) replacing 60 deep copies; property test:undo∘redo = idacross random edit scripts. (P1) - Hot-path shapes: precomputed lowercase search haystack (P4); sheet drag position as shader-instance offset instead of margin relayout (P2); document the linear-scan element threshold or add a grid index if koboyo is meant to scale (P5).
- Scroll container back into insurance + teach UI tests to scroll-to-widget, removing the 390×1280 hack. (A4)
- Test debt: id-based locators everywhere (B3 done); panic idioms →
if let/Optioncombinators (B2); renameMut/Wht/Deepto speaking names (Q2).
Exit: assessment re-scored; target ≥ 7.5 overall with Design ≥ 7.
Standing rules for every phase
- Tranche discipline (user requirement): fetch → reconcile (remote improvements win where they're better; local reorganizations preserved; no force-push) → run the matrix → push. One tranche per phase minimum, more when a phase touches all three crates.
- DSL landmines list (
plans/README.md) applies to every executor. - Coverage report regenerated at the end of Phases 2, 3 and 5; deltas quoted in tranche messages.
- The restraint list (canvas 1:1, PageFlip, wheel zoom) is load-bearing: PRs that "improve" those get rejected.