1d194e0f23
req: performance/006
13 KiB
13 KiB
Hemx v1 implementation plan
Authority: REQUIREMENTS.md. Product evidence: docs/v1-product-evidence.md.
This file is an execution cursor, not requirement authority or release permission.
Publishing, deployment, artifact upload, and package-registry mutation are out of scope.
Product boundary
Hemx v1 keeps server-rendered HTML and ordinary Rust as the default. Generated
resources and the versioned EffectBatch are the one UI contract. Client-local
WASM and durable sync are optional execution layers, not a component framework.
Hemplate remains the rendering/Surface foundation; application auth, persistence,
encryption, retention, backup, and deployment policy remain host concerns.
Slice 1 — one real client-local handler
- User value: a Rust author marks one high-frequency handler local and gets immediate browser behavior without app-authored JavaScript or a request.
- State: Done.
hemx-buildvalidates same-origin client module metadata and generates the WASM import, initialization, handler registration, fingerprint, and ready marker. Client handlers receive versionedClientEvent/root-ownedClientState; incompatible input is rejected before handler execution, reports an actionablehemx:client-error, restores pending UI, and invokes an explicitly declared server fallback. Real WASM applies the ordinary generated-targetEffectBatchwith zero request on valid input. - Build: add the smallest optional
hemx-wasmboundary for#[hemx::handler(client)]; export only opted-in handlers; generate typed event/state ABI glue; run one existing generated-target interaction through the ordinaryEffectBatchinterpreter; preserve an explicit native/server fallback. - Refusals: no VDOM, component lifecycle, global store, sync queue, second effect protocol, or generic WASM framework.
- Requirements:
client_local/001-010,security/001,security/005-006,performance/003,v1_release/001. - Proof:
cargo test -p hemx-wasm --test browser client_handler_applies_effect_batch_without_network -- --exactserves only generated template HTML, the ordinary runtime, and generated client bootstrap; it visibly updates a generated target through real WASM, keeps the resource count unchanged for valid input, and proves invalid state diagnostics, pending restoration, and one declared fallback request. Formatting, workspace tests, strict all-target Clippy, and wasm-target build pass.
Slice 2 — direct manipulation that survives interruption
- User value: Kanban drag/reorder follows the pointer immediately, remains keyboard operable, and cannot apply stale work after cancellation or root removal.
- State: Done. The canonical Kanban client board is rendered through Hemplate and generated resources, then reordered by its real WASM handler for drag/drop and Arrow-key interaction. Client-local runs use validated
latest/droppolicy; stale/unmounted completions cannot apply effects; moved-card focus, live status, reduced-motion state, root cleanup, and a measured sub-100 ms local response are browser-proven. - Build: use the client handler in the canonical Kanban path; add cancellation/supersession, root-owned state cleanup, keyboard equivalent, focus/status behavior, reduced-motion behavior, and measured response/frame budgets.
- Refusals: no persistence, collaboration, or animation framework yet.
- Requirements:
client_local/011-014,accessibility/001-007,operations/002-003,performance/001,performance/003,milestone/001. - Proof:
cargo test -p hemx-wasm --test browser kanban_reorder_has_pointer_keyboard_focus_and_reduced_motion_parity -- --exactcovers real-WASM pointer and keyboard reorder, focus/status, reduced motion, and the 100 ms response budget; the client-handler browser proof covers cancellation, removal, error recovery, zero-request behavior, and root cleanup.
Slice 3 — durable offline command log
- User value: an opted-in Kanban mutation remains available after network loss and browser reload without storing DOM patches as truth.
- State: Complete — the app-owned
reorder_cardcommand is transactionally persisted with schema, actor, session, causal id, and app payload before projection; an app-owned service worker caches only the generated shell/resources, and reload restores the projection after the fixture server is stopped and proven unreachable. Native recovery controls export a versioned credential-free command envelope, delete queued commands while preserving actor/causal identity, and reset command data, identity, cache, and registration behind explicit confirmation. Unknown schemas and malformed current-schema records stop before projection with explicit recovery diagnostics. Transaction conflicts and injected quota exhaustion neither project nor emit durability claims and remain recoverable through export/delete/reset. Replay is preflighted before effects, capped by the app at 64 commands, and measured against a 100 ms browser budget. A programmatic queued/busy state appears within the 100 ms direct-interaction budget before blocked persistence completes. The ordinary server-first route loads only the fingerprinted base runtime and creates no client root, service worker, or IndexedDB database; PWA/WASM policy remains app-owned and opt-in. - Build: add an optional durable command-log adapter around platform transactional storage; persist versioned command ids and app payload before projection; restore projection after reload; expose queue state, export/delete/reset, quota/corruption failure, and migration refusal.
- Refusals: no server reconciliation, CRDT, mandatory IndexedDB, credential storage, or policy hidden in core.
- Requirements:
local/001-004,sync/009,sync/014-015,sync/020,security/007,accessibility/004,client_local/013,performance/003,performance/005-006. - Proof:
cargo test -p hemx-wasm --test browser kanban_command_persists_before_projection_and_restores_after_reload -- --exactproves transactional persist-before-project ordering, app-owned shell caching, current-version replay after a real Firefox reload with the fixture server unreachable, stable identity metadata, and explicit unknown-schema refusal through real WASM.cargo test -p hemx-wasm --test browser kanban_command_export_delete_and_reset_are_recoverable -- --exactproves accessible export/delete/reset entry points, versioned credential-free export, confirmation before destructive actions, preserved identity after queue deletion, and fresh identity/baseline projection after reset.cargo test -p hemx-wasm --test browser kanban_persistence_failure_does_not_project_and_recovers -- --exactproves transactional failure does not project or emitkanban:command-persisted, reports non-payload stage/code diagnostics, and recovers through the ordinary deletion path.cargo test -p hemx-wasm --test browser kanban_corrupt_command_refuses_projection_and_recovers -- --exactproves strict current-schema validation, no partial projection, visible non-payload diagnostics, raw versioned export for recovery, and ordinary deletion recovery.cargo test -p hemx-wasm --test browser kanban_replay_is_bounded_and_within_budget -- --exactproves 64-command preflight/replay within the 100 ms browser budget, zero partial projection at 65 commands, and export/delete recovery.cargo test -p hemx-wasm --test browser kanban_quota_failure_is_fail_closed_and_recoverable -- --exactproves quota-specific fail-closed behavior, no false durability event, transactional metadata rollback, and export/delete/reset recovery.cargo test -p hemx-wasm --test browser kanban_queued_status_precedes_durable_projection_within_budget -- --exactproves queued/busy feedback within theperformance/003andclient_local/013100 ms budget while persistence is blocked, followed by durable projection only after commit.cargo test -p hemx-kanban-example --test browser_e2e server_first_route_does_not_load_optional_client_assets -- --exactproves the server-first route loads only its fingerprinted base runtime and creates no optional client root, PWA/WASM request, service worker, or IndexedDB database.
Slice 4 — authoritative reconnect and convergence
- User value: offline and concurrent work reconnects without duplicate mutation, silent loss, stale authorization, or ambiguous conflict.
- State: Ready — Slice 3 is complete; begin with one idempotent server command and canonical acknowledgement through a real reconnect transport before adding conflicts or multi-tab policy.
- Build: materialize
hemx-syncover an integration transport with idempotent server command processing, snapshot/change cursor, durable acknowledgements, bounded ordered replay, current auth checks, rejection/conflict results, canonical replacement, reconnect jitter/backoff, multi-tab coordination, and redacted diagnostics. - Refusals: no default CRDT, transport in core, cached enqueue-time permission, unbounded queue, or silent last-write-wins policy.
- Requirements:
sync/001-023,operations/001-005,security/002-005,performance/004-005. - Proof: deterministic browser/server test covers offline → reload → reconnect, duplicate and reordered delivery, authorization revocation, rejection, conflict, missing history/fresh snapshot, two tabs, backpressure, and final convergence.
Slice 5 — local-first multiplayer Kanban milestone
- User value: the complete north-star app demonstrates SSR-first startup, direct manipulation, offline durability, optimistic projection, reconciliation, and live presence as one comprehensible workflow.
- State: Blocked by Slice 4.
- Build: connect the previous slices in the canonical Kanban example; keep native server-rendered fallback; add presence and server-canonical conflict presentation; exercise deploy fingerprint recovery and accessible online/offline/conflict state.
- Refusals: no demo-only runtime, hidden app JS, proprietary service, or requirement to load collaboration code for server-first apps.
- Requirements:
milestone/001,v1_release/001-002,accessibility/001-007,operations/006,performance/006. - Proof: one browser journey covers SSR/no-script fallback, local drag, keyboard reorder, offline/reload, concurrent peer edit, reconnect/convergence, presence, conflict/rejection recovery, mixed-version reload, and optional-asset isolation.
Slice 6 — production integration reference
- User value: adopters can copy a proven boundary for durable storage, auth, transactions, security controls, observability, and restart recovery without hemx owning vendor policy.
- State: Ready after public execution/sync contracts stabilize.
- Build: evolve one existing reference app using ordinary integration adapters; add durable app storage, authenticated/authorized allowed and denied mutations, CSRF/origin checks, transaction rollback, bounded input, structured failures, health/readiness, tracing/metrics hooks, and restart/deploy recovery.
- Refusals: no built-in database/auth provider, compliance claim, telemetry vendor, deployment system, or repository framework.
- Requirements:
security/001-009,operations/001-008,v1_release/003, existingadapter/*,integration/*, anddiagnostics/*contracts. - Proof: end-to-end test survives process restart and mixed deployment, proves allowed/denied/rolled-back mutations and redacted diagnostics, and maps each framework-owned ASVS-relevant control to a failing/passing case.
Slice 7 — v1 compatibility and closure
- User value: maintainers and adopters receive a reproducible, migration-aware v1 with no known material contradiction and no hidden publication side effect.
- State: Blocked by Slices 1-6 and explicit authority for any missing local audit tool installation.
- Build: freeze the supported Rust/browser/WASM/integration matrix; reconcile public/generated/Surface/symbol/wire/runtime/persisted-schema compatibility; add migration fixtures; make canonical examples compatibility tests; update the progressive tutorial path; run all local release gates and disposition every P0/P1, advisory, unsafe-code, license, performance, accessibility, and documentation finding.
- Refusals: no publish, deploy, upload, store submission, speculative feature, or weakening a gate to make it pass.
- Requirements:
v1_release/001-010,versioning/*,test/*,diag/*,performance/*,security/008, and all requirements changed by the preceding slices. - Proof: clean-tree formatting, workspace tests, strict all-target Clippy, compile-fail, browser/WASM/offline/multiplayer scenarios, benchmark budgets, approved pinned lockfile audit, requirements proof audit, docs/examples checks, and independent contradiction review all pass with no unresolved P0/P1.