Implementation plan
34. A Compose-first implementation plan
34.1 Sequence by risk, not by the number of component names
HLD — Arrows show prerequisites. Manna pulls the portable host and React slice forward into K1; other CMP consumers retain the direct path. Open the diagram for full size.
The first objective is a usable CMP vertical slice: a graph-bound form and conversation region with correct state ownership, theme switching, adaptive presentation and one convincing tactile interaction. A large catalogue built before these boundaries are proven would multiply the cost of correcting them.
The finalized renderer targets are React web/JS and Compose Multiplatform. Ordinary CMP consumers may keep the direct path. Neutral contracts and independent behavior remain early constraints. Manna's migration requires one common Kotlin screen composition, so its K1 moves the portable host and React web proof ahead of broad product porting. A later generic React rollout cannot substitute for this early dual-renderer gate.
Figure 56. The critical path delivers CMP functionality first. Shared contracts and a small portability probe prevent the first renderer from defining the universal API accidentally. React web qualification follows the applicable consumer gate; Manna requires an early two-renderer proof. See the illustrated PDF for the diagram.
Tasks below identify prerequisites and observable completion criteria. They are dependency units rather than calendar estimates. Platform qualification can run in parallel where the shared contracts are stable, while changes to core identity or behavior require coordination.
34.2 Foundation: neutral meaning and testable behavior
| Task | Prerequisites | Deliverable and completion criterion |
|---|---|---|
| S01 — Establish package boundaries | None | Separate neutral contracts, graph integration and toolkit implementations. Add dependency checks that reject Compose or React types in the neutral layer and prevent a graph–UI module cycle. |
| S02 — Define identities and boundary values | S01 | Define component, entry, mount and generation identities; text, asset and logical-geometry values; bounded codecs and validation findings. Round-trip representative values and reject incompatible fingerprints. |
| S03 — Implement independent behavior kernels | S02 | Implement button, toggle and selection behavior without UI imports. Tests cover concurrent focus/hover/press, cancellation, controlled-input changes and duplicate activation delivery. |
| S04 — Generate the catalogue projections | S02 | Generate Kotlin/CMP and Kotlin/JS React bindings, boundary schemas and test metadata from one definition. Optional TypeScript declarations support other consumers; Manna maintains no handwritten TS screen layer. |
| S05 — Probe the portable host seam | S03, S04 | Build a tiny custom-Applier tree with a text node, button and keyed list. Verify insert, move, remove and commit publication. No production screen is forced through this path. |
The neutral layer is intentionally small. It should not absorb a layout engine, a new application service registry or every property in Material. Its purpose is to make future implementations agree on values and behavior.
S03 is complete when a behavior trace can be replayed independently of a window. S05 is complete when the portable node vocabulary can express the initial controls without using toolkit-specific values. Neither task establishes accessibility or performance on a device; those belong to the realization tasks.
The early TypeScript projection can be checked without shipping a React web renderer. It verifies that the contract actually has a reasonable cross-language shape. Unsupported local-only slots remain explicitly marked rather than translated into misleading generic types.
34.3 First CMP slice: controls, themes and graph ownership
| Task | Prerequisites | Deliverable and completion criterion |
|---|---|---|
| C10 — Theme resolution and Material adapter | S02, S04 | Implement token resolution, complete supported Material roles, typography, shape and nested scopes. Two modes and two distinct recipes render coherently without losing a controlled draft. |
| C11 — Button and action realization | S03, C10 | Adapt native interaction and semantics to one activation path. Implement normal, busy, unavailable, focus and pointer states with the same headless behavior contract. |
| C12 — Editing and field contracts | S03, C10 | Integrate platform editing with revisioned draft updates. Test selection, IME composition, paste, validation failure and stale acknowledgments. |
| C13 — Selection, dialog and overlay primitives | C11, C12 | Implement controls needed by a real form, including focus entry/return, dismissal and theme propagation to overlays. Keyboard and accessibility tests cover complete interactions. |
| C14 — Graph-bound Surface sessions | S02, C11 | Bind models and actions through graph-owned ports. Introduce entry-aware context and explicit mount lifetime. Two mounts cannot overwrite one shared active-entry slot accidentally. |
C10 should correct the role-mapping problem before new skins multiply it. A theme preview must exercise the controls that actually consume those roles, including fields, overlays and disabled content. Merely comparing the palette objects is insufficient.
C12 is a particularly important integration test. The editor must remain responsive while the graph draft owner receives updates, and older results must not overwrite newer input. A theme or layout change must not be used as a reason to reconstruct the draft.
C14 should use a keyed session example rather than only one static screen. A conversation opened twice is a useful test because it reveals the difference between business identity and presentation identity. Its actions remain typed and subject to application policy.
Desktop can provide a fast iteration host, but touch, keyboard and native mobile lifecycle behavior need representative Android and iOS qualification early. A successful desktop preview is not evidence for all CMP targets.
34.4 Adaptive presentation and the tactile differentiator
| Task | Prerequisites | Deliverable and completion criterion |
|---|---|---|
| C20 — Measured adaptive scopes | C14 | Replace device-name branching with window environment and local constraints. Implement list-detail and supporting-pane plans. Resize repeatedly while preserving entry identity and draft state. |
| C21 — Core motion and transitions | C11, C13, C20 | Implement interruptible press, enter/exit and navigation motion with a deterministic test clock. Verify reversal, resize during transition, reduced motion and correct input admission. |
| C22 — Shared tactile field | S03, C21 | Implement bounded impulses and explicit coupling. One press affects its face, a second component and a background input locally. Tests reject duplicate/foreign-scope impulses and stop settled work. |
| C23 — Shader and sensory adapters | C22 | Implement one supported procedural treatment plus semantic haptics. Cache shader programs, update uniforms locally, qualify fallback and emit each sensory cue once. |
| C24 — Product organisms | C12, C13, C20 | Compose a message composer, event card and participant picker from the tested catalogue. They accept models/events and do not acquire repositories internally. |
The tactile field should be proven with one carefully controlled scene rather than a large catalogue of unrelated effects. The scene needs a visible causal relationship: contact, local compression, neighboring response and decay. It also needs a quiet profile that preserves the same usable controls.
C23 does not require every shader backend at once. Qualify one CMP realization and an explicit static or simpler fallback. Additional backends follow the same uniform, resource and capability contract. A failed effect must leave readable content and operable controls.
C20 and C21 are connected. A panel can be resized during a transition, and its focus owner must remain correct. The qualification suite should deliberately combine these changes rather than test each feature only while the rest of the application is idle.
34.5 Delivery, observation and a release-quality CMP application
| Task | Prerequisites | Deliverable and completion criterion |
|---|---|---|
| C30 — Asset manifest and request policy | S02, C10 | Implement size-aware media requests, variant selection, reserved geometry, privacy scope and cancellation. Verify transfer/decode dimensions and cleanup after account changes. |
| C31 — Virtualized collection and anchor policy | C20, C30 | Build a paged timeline with stable keys and item-relative anchors. Late media and inserted rows do not unexpectedly move the content being read. |
| C32 — Performance observation | C14, C21, C30 | Add bounded renderer, action and resource diagnostics correlated with graph ownership. Define named scenarios and actual observation limits. |
| C33 — Custom engine boundary | C13, C14, C32 | Integrate one graph canvas or editor with lifecycle, focus, resource and semantic-command contracts. Closing or hiding it releases the declared expensive resources. |
| C34 — CMP qualification matrix | C23, C24, C31, C32, C33 | Run representative native/desktop and qualified web-canvas scenarios. Exercise large text, direction, interruption, low memory and repeated view replacement in release-like builds. |
C30 is complete only when resource policy is visible in requests and measurements. An image-format conversion alone does not establish size-aware decoding or bounded residency. Private media tests include logout and permission changes, not just cache hits.
C32 should make a regression explainable. A finding can identify a widened subscription, an unnecessarily large decode or an effect that continued while hidden. The system should not export every frame as a graph transaction or log private field values by default.
C34 establishes the first production-quality Surface profile. It is a set of supported combinations, not a blanket claim about all future platforms. The application should be useful without agents and with optional effects disabled.
34.6 Integrate graph updates without building another updater
| Task | Prerequisites | Deliverable and completion criterion |
|---|---|---|
| G40 — Activated-region observation | C14, C34 | Connect Surface to the existing graph activation result. A changed region receives coherent definitions/bindings, preserves declared state and rejects retired-generation presentation work. |
| G41 — Approved generated region | S04, C24, G40 | Permit an agent to propose an event-planning region using the catalogue and granted graph actions. Invalid proposals leave a stable fallback and existing edits intact. |
| G42 — Interactive-update scenarios | G40, G41 | Update supporting content during typing, resize and permission changes. Active fields retain identity or follow an explicit handoff/defer policy. No new updater is implemented inside Surface. |
These tasks assume the lower-level subgraph-update capability. They test the UI boundary's response, not release distribution, Hermes loader internals or state-migration machinery owned elsewhere.
G41 begins with known organisms and approved slots. It does not require arbitrary generated code to execute in the user's application. A more powerful execution profile can be integrated later through the graph system without changing which layer owns application authority.
The essential acceptance condition is continuity: activated structure, action bindings and event admission agree. A newly displayed action must not use an incompatible old handler table, and a retired control must not invoke a newly reused callback slot.
34.7 React web/JS and the portable Kotlin screen gate
| Task | Prerequisites | Deliverable and completion criterion |
|---|---|---|
| R50 — Kotlin/JS contract consumption | S04 | Consume the Kotlin behavior exports and typed React bindings. Verify property validation, stable snapshots and semantic traces before expanding the catalogue. |
| R51 — React web/JS realization | R50 | Implement DOM controls, themes/style lowering, overlays, assets and graph subscriptions through Kotlin React. Qualify browser input, loading and interaction. RSD is not a prerequisite. |
| R55 — Portable Kotlin composition | S05, R51, C12, C13 | Build the Surface-specific Compose Runtime authoring adapter and CMP/React host mappings. One shared composition declares a keyed list, controlled field, action, supporting pane and inert island. No toolkit-specific feature tree is duplicated. |
| R52 — Cross-renderer conformance | R55, C14; G42 for activated regions | Replay keys, editing, focus, lifecycle, stale callbacks and workflow traces on CMP and React web. Manna K1 requires this slice early; complete catalogue and graph-update breadth follow their own gates. |
R51 is the React delivery path. R55 is required for Manna's shared screens but remains optional for direct CMP consumers. The former R53 React Native and R54 custom React-to-CMP tracks are deferred and excluded from current delivery. They contribute no prerequisites, acceptance work or renderer targets here.
The Manna design benchmark adds concrete K1, K3 and K4 proof slices. A library release can qualify direct CMP controls while Manna remains blocked on its portable authoring requirement.
A later renderer should mostly add adapters and conformance evidence. If it requires changing the meaning of every component, the earlier neutral contracts were not actually neutral. The early S04 and S05 probes reduce that risk, while the CMP application provides practical feedback about which contracts are worth stabilizing.
34.8 The minimum complete vertical slice
The first integrated demonstration should contain one graph-owned conversation or form, two visual languages, compact and expanded layouts, a revisioned field, local press feedback, one bounded cross-component impulse, size-aware media, a meaningful scroll anchor and a supported graph-updated region.
Run it while changing theme, resizing, typing, loading media and failing an application operation. Confirm that the draft survives, focus remains useful, the operation's result is truthful, hidden work stops and the inspector can explain the resulting cost.
This is the point at which the architecture's main promises become observable. A large list of component names is not an equivalent milestone. Direct CMP can deliver its first experience independently. Manna's migration is complete only when its one Kotlin composition passes the same supported workflows through both React web and CMP, including qualified editor engines.