- 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
101 lines
6 KiB
Markdown
101 lines
6 KiB
Markdown
# 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.
|