# 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). 1. **Pin upstream**: `setup_makepad.sh` checks out `b41e740` explicitly (`git fetch --depth 1 origin b41e740 && git checkout b41e740`); `git apply --check` failure aborts loudly. Pin the Rust toolchain (`--default-toolchain 1.98.0`). (S1, S2) 2. **Coverage harness** (this tranche): temp-env `cargo-llvm-cov` + `llvm-tools-preview` in `/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.rs` registration glue) excluded via `--ignore-filename-regex`; summary committed to `docs/coverage/COVERAGE.md`; uncovered model branches get unit tests in the same tranche; artifacts (`.profraw`, cov target dir, tool binaries) cleaned after. 3. **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) 4. **Token rotation** on gitdab; pushes via credential helper. (S4) 5. **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)* 1. **Router**: replace `handle_actions` if-chains with a dispatch table (`&[(LiveId, Msg)]` → `fn update(flow, Msg) -> Fx`), one per crate; exhaustive, testable. (A2) 2. **Dirty-flag chrome**: `refresh_chrome` takes the `Fx`/diff of what changed; full resync only on screen change. Prerequisite for animations not being stomped. (A3, P3) 3. **Undo rework**: command-pattern deltas (or `Arc<[Element]>` structural snapshots) replacing 60 deep copies; property test: `undo∘redo = id` across random edit scripts. (P1) 4. **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). 5. **Scroll container back into insurance** + teach UI tests to scroll-to-widget, removing the 390×1280 hack. (A4) 6. **Test debt**: id-based locators everywhere (B3 done); panic idioms → `if let`/`Option` combinators (B2); rename `Mut`/`Wht`/`Deep` to 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.