WAP LabsProject atlas

docs/waves/engine_host_frame_work_items.md

Engine-Host Frame Migration Work Items

Purpose: execution board for migrating Waves runtime/host integration to EngineFrame + EngineInputEvent.

Status keys:

  • todo
  • in-progress
  • blocked
  • done

Archive:

  • docs/waves/ENGINE_HOST_FRAME_WORK_ITEMS_ARCHIVE.md

Program Guardrails

  1. Keep changes layered:
  • engine runtime logic in engine-wasm/
  • host rendering/input wiring in browser/ and engine-wasm/host-sample/
  • no WBXML parsing in host TypeScript
  1. Contract-first policy:
  • update contract surfaces before implementation cutover
  • keep native and wasm behavior aligned
  1. Determinism policy:
  • preserve deterministic navigation, focus, and frame output ordering
  • no host-timing dependent layout logic
  1. Scope policy:
  • no broad refactor bundles; deliver phased, testable slices

Ticket Template

  1. ID
  2. Status
  3. Depends On
  4. Files
  5. Build
  6. Tests
  7. Accept
  8. Notes (optional)

Phase F0: Contract and API Introduction

F0-01 Define canonical frame/input contract types

  1. Status: done
  2. Depends On: none
  3. Files:
  • engine-wasm/engine/src/render/*
  • engine-wasm/contracts/wml-engine.ts
  • browser/src-tauri/src/contract_types.rs
  • browser/src-tauri/src/bin/generate_contracts.rs
  1. Build:
  • Add additive types for:
    • EnginePresentationFrame with ordered rows/segments, focus/selection, and affordances
    • EngineInputEvent
  • Keep the Tauri-owned EngineFrame only as a transitional snapshot/render/presentation envelope.
  • Defer EngineCommand; no command queue was required for the stable F0 boundary.
  • Keep legacy RenderList contract available.
  1. Tests:
  • contract generation succeeds
  • TypeScript compile in browser/frontend
  1. Accept:
  • New frame/input types are exported in Rust and TS contracts without breaking current hosts.
  1. Notes:
  • WBP-06 v1 uses engine-owned EnginePresentationFrame and EngineInputEvent DTOs. The host-owned EngineFrame remains a transitional envelope containing snapshot, legacy render output, and the canonical presentation payload; it does not own presentation semantics.
  • Logical primary, task, and back associations avoid vendor-specific physical key claims.

F0-02 Add additive engine APIs with compatibility wrappers

  1. Status: done
  2. Depends On: F0-01
  3. Files:
  • engine-wasm/engine/src/lib.rs
  • engine-wasm/contracts/wml-engine.ts
  • browser/src-tauri/src/lib.rs
  • browser/contracts/generated/engine-host.ts
  1. Build:
  • Add:
    • renderFrame()
    • handleInput(event)
  • Keep:
    • render()
    • handleKey()
  • Implement wrapper behavior so outputs stay equivalent for key-only flow.
  1. Tests:
  • cd engine-wasm/engine && cargo test
  • cd browser/src-tauri && cargo test
  1. Accept:
  • Old and new APIs return equivalent behavior for existing fixtures and key sequences.
  1. Notes:
  • Native and WASM renderFrame()/handleInput() share the legacy layout, key, and task execution paths. Action activation is bound to the current frame identity and rejects stale input before mutation.

F0-03 Contract drift guardrails for frame/input interfaces

  1. Status: done
  2. Depends On: F0-01
  3. Files:
  • scripts/ (new contract drift check)
  • .github/workflows/*
  • docs/waves/CONTRACT_REQUIREMENTS_MAPPING.md
  1. Build:
  • Add CI check that generated TS contracts are in sync with Rust contract types.
  1. Tests:
  • intentional drift causes CI/check failure
  1. Accept:
  • contract changes cannot merge with stale generated outputs.
  1. Notes:
  • The existing CI contracts:check lanes now regenerate the frame/input Rust projections for both engine-wasm/contracts/generated/runtime-dtos.ts and browser host/command contracts. The Tauri generated schema gate covers the added command allowlist.

Phase F1: Host Rendering Migration

F1-01 WASM host sample frame renderer adoption

  1. Status: done
  2. Depends On: F0-02
  3. Files:
  • engine-wasm/host-sample/renderer.ts
  • engine-wasm/host-sample/main.ts
  • engine-wasm/README.md
  1. Build:
  • Consume renderFrame() and draw from frame contract.
  • Keep behavior and appearance stable.
  1. Tests:
  • host sample manual fixture checks
  1. Accept:
  • sample no longer depends on legacy RenderList call path.
  1. Notes:
  • Implemented by PR #519; the host sample now consumes renderFrame() presentation rows while retaining equivalent focus and softkey behavior.

F1-02 Tauri frontend viewport migration to Canvas2D

  1. Status: done
  2. Depends On: F0-02
  3. Files:
  • browser/frontend/src/app/browser-shell-template.ts
  • browser/frontend/src/app/browser-presenter.ts
  • browser/frontend/src/styles.css
  • browser/frontend/src/app/browser-presenter.test.ts
  1. Build:
  • replace HTML line injection viewport path with canvas renderer adapter.
  • preserve skeleton, status, and timeline UX.
  1. Tests:
  • pnpm --dir browser/frontend test
  • pnpm --dir browser/frontend build
  1. Accept:
  • viewport rendering no longer uses innerHTML for deck content.
  • draw output parity remains stable for local fixtures.
  1. Notes:
  • Implemented by PR #520; the Tauri frontend uses the Canvas2D renderer and a synchronized semantic viewport projection for accessibility and deterministic test harnesses.
  • PR #527 subsequently added the defensive host-output cap and single-pass bounded engine frame construction without reopening this completed migration ticket.

F1-03 Navigation-state integration with frame rendering

  1. Status: done
  2. Depends On: F1-02
  3. Files:
  • browser/frontend/src/app/navigation-state.ts
  • browser/frontend/src/app/browser-controller.ts
  • browser/frontend/src/app/navigation-state.test.ts
  1. Build:
  • keep render/snapshot sequencing deterministic with engineRenderFrame.
  1. Tests:
  • navigation-state tests cover render-after-load and render-after-input ordering.
  1. Accept:
  • no regressions in load/fetch/back/external-intent flows.
  1. Notes:
  • NavigationHooks.onFrame is the single committed-frame publication boundary; snapshot and render projections come from the same accepted EngineFrame.
  • Load, input, Back, timer, and clear-intent paths consume the existing atomic frame-returning host APIs. Generation checks suppress cancelled and stale completions before publication.
  • Host-history Back stages its deck load and optional card restoration, then publishes only the final restored frame.
  • Focused sequencing evidence is in navigation-state.frame.test.ts and browser-controller.timer.test.ts; the existing navigation/controller suites retain local, network, reload, same-deck, Back, cancellation, and external-intent coverage.

Phase F2: Input Event Expansion

F2-01 Add click event path with deterministic hit resolution

  1. Status: done
  2. Depends On: F0-02
  3. Files:
  • engine-wasm/engine/src/lib.rs
  • engine-wasm/engine/src/layout/*
  • browser/frontend/src/app/browser-controller.ts
  • engine-wasm/host-sample/main.ts
  1. Build:
  • add host click -> EngineInputEvent::Click routing.
  • engine resolves click through frame/hit regions, not host-side link lookup.
  1. Tests:
  • engine fixture tests for click-target determinism
  • host integration tests for click navigation
  1. Accept:
  • click activation behavior matches keyboard activation targets.
  1. Notes:
  • Frame contract version 2 adds ordered half-open logical hit regions and frame-bound EngineInputEvent::Click { frameId, x, y }. The engine resolves the advertised focus:* action and retains stale-frame rejection before mutation.
  • Canvas and host-sample adapters convert scaled pointer pixels into the engine column/row grid without link, control, or WML lookup. Wrapped links, input/select controls, empty space, boundaries, frame mismatch, native/WASM parity, and keyboard-equivalent outcomes are covered by focused tests and the F2-01 executable story.

F2-02 Add scroll event path and viewport offset semantics

  1. Status: done
  2. Depends On: F2-01
  3. Files:
  • engine-wasm/engine/src/lib.rs
  • engine-wasm/contracts/wml-engine.ts
  • browser/frontend/src/app/browser-controller.ts
  1. Build:
  • support EngineInputEvent::Scroll.
  • define deterministic scroll clamping and frame offset behavior.
  1. Tests:
  • scroll boundary and repeatability tests in engine.
  1. Accept:
  • identical event traces produce identical visible frame windows.
  1. Notes:
  • Frame contract version 3 adds a neutral 20-row Class C reference window with offsetRow and contentRows; presentation rows and hit regions are projected relative to the visible window.
  • EngineInputEvent::Scroll { frameId, deltaRows } is stale-frame protected and clamps signed row deltas to the content bounds. Browser and host-sample wheel adapters normalize each physical wheel event to one row without inspecting deck content.
  • Native boundary, repeatability, click-after-scroll, browser integration, and the F2-02 executable story cover the acceptance path.

F2-03 Softkey/input abstraction alignment

  1. Status: done
  2. Depends On: F2-01
  3. Files:
  • browser/frontend/src/app/keyboard.ts
  • browser/frontend/src/app/browser-controller.ts
  • engine-wasm/contracts/wml-engine.ts
  1. Build:
  • map host keyboard/buttons into unified EngineInputEvent path.
  • keep legacy key APIs as compatibility layer until cutover.
  1. Tests:
  • keyboard and control-button regression tests.
  1. Accept:
  • single input abstraction path is used in host application code.
  1. Notes:
  • Browser keyboard intents and the Up, Select, and Down controls now construct EngineInputEvent::Key and use the same local/network handleInput frame path as pointer input.
  • The native/WASM handleKey methods and navigation-state key adapter remain compatibility surfaces until F4; primary browser-controller code no longer calls them.
  • Browser integration coverage asserts physical keyboard and control-button parity, the absence of legacy key-command calls, direct committed-frame publication, and existing failure/cancellation behavior. The F2-03 Waves executable story covers button and keyboard sources.

Phase F3: Engine Internal Boundary Split

F3-01 Separate layout and paint phases

  1. Status: todo
  2. Depends On: F0-02
  3. Files:
  • engine-wasm/engine/src/layout/*
  • engine-wasm/engine/src/render/*
  • engine-wasm/engine/src/lib.rs
  1. Build:
  • move draw-command emission into paint pass over layout output.
  • preserve current command ordering and focus semantics.
  1. Tests:
  • existing render snapshot tests
  • new tests for layout-output determinism independent from paint
  1. Accept:
  • layout and paint responsibilities are explicit and test-covered.

F3-02 Frame snapshot parity harness (native + wasm)

  1. Status: todo
  2. Depends On: F3-01
  3. Files:
  • engine-wasm/engine/src/lib.rs
  • engine-wasm/engine/tests/* (new if needed)
  • docs/waves/SPEC_TEST_COVERAGE.md
  1. Build:
  • add parity-critical snapshots for renderFrame and input traces.
  1. Tests:
  • cd engine-wasm/engine && cargo test
  1. Accept:
  • frame and navigation parity is verified across targets for critical flows.

Phase F4: Cutover and Legacy Removal

F4-01 Remove legacy render/input API from host paths

  1. Status: todo
  2. Depends On: F1-03, F2-03, F3-02
  3. Files:
  • browser/frontend/src/*
  • engine-wasm/host-sample/*
  • browser/contracts/generated/*
  • engine-wasm/contracts/wml-engine.ts
  1. Build:
  • stop calling legacy render()/handleKey() in host code.
  • retain compatibility only where needed for transition windows.
  1. Tests:
  • browser frontend tests/build
  • host-sample smoke checks
  1. Accept:
  • all active hosts run on frame/input API path.

F4-02 Legacy contract and wrapper removal (final)

  1. Status: todo
  2. Depends On: F4-01
  3. Files:
  • engine-wasm/engine/src/lib.rs
  • engine-wasm/contracts/wml-engine.ts
  • browser/src-tauri/src/contract_types.rs
  • browser/src-tauri/src/bin/generate_contracts.rs
  • docs references to legacy API
  1. Build:
  • remove legacy RenderList/DrawCmd wrappers and key-only APIs when no longer used.
  1. Tests:
  • engine, browser frontend, and tauri host tests/builds
  1. Accept:
  • contract surface is single-path (EngineFrame + EngineInputEvent) and documented.

Program Tracking

Cross-reference docs:

  • migration architecture: docs/waves/ENGINE_HOST_FRAME_MIGRATION_PLAN.md
  • waves integration board: docs/waves/WORK_ITEMS.md
  • maintenance board: docs/waves/MAINTENANCE_WORK_ITEMS.md

Completion gate:

  • all F0-F4 tickets marked done
  • parity gates in docs/waves/SPEC_TEST_COVERAGE.md updated and passing
  • contract mapping updated in docs/waves/CONTRACT_REQUIREMENTS_MAPPING.md