From 0d49007c61575471c19af08eb6a7e9f5ab9401f5 Mon Sep 17 00:00:00 2001 From: slhx agent Date: Mon, 13 Jul 2026 11:50:18 +0200 Subject: [PATCH] docs(v1): define evidence-backed production contract req: client_local/005\nreq: sync/009\nreq: accessibility/001\nreq: operations/001\nreq: security/001\nreq: performance/001\nreq: v1_release/001 --- AGENTS.md | 3 +- PLAN.md | 81 ++++++++++++-- README.md | 11 +- REQUIREMENTS.md | 217 +++++++++++++++++++++++++++++++++++- docs/v1-product-evidence.md | 166 +++++++++++++++++++++++++++ docs/v1-readiness.md | 25 ++++- 6 files changed, 481 insertions(+), 22 deletions(-) create mode 100644 docs/v1-product-evidence.md diff --git a/AGENTS.md b/AGENTS.md index 1c79a03..6c1788d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,6 +9,7 @@ Keep it stable. Prefer pointers to canonical sources over copied structure, file ## Agent workflow - Start from product intent and requirements; inspect code only after the target behavior is clear. +- For v1 work, read `docs/v1-product-evidence.md`, then `REQUIREMENTS.md`; use `PLAN.md` only as the mutable implementation cursor. - Read `REQUIREMENTS.md` before changing behavior. - If behavior changes, update `REQUIREMENTS.md` in the same change. - If implementation work does not change durable product obligations, acceptance, safety/recovery behavior, or verification duties, say `REQUIREMENT IMPACT: none` in the handoff and why. @@ -25,7 +26,7 @@ Keep it stable. Prefer pointers to canonical sources over copied structure, file - Every behavior-changing or requirement-changing commit should cite relevant requirement IDs in the commit body or trailers using `req: /001`. - Use commit history for evolution: `git log --grep 'req: parser/012'` should find the commits that changed that behavior. - Use the current tree for state: `REQUIREMENTS.md`, citations, tests, and `redgate health` describe what is true now. -- Before committing requirement or behavior changes, run relevant tests and `redgate health --strict`. +- Before committing requirement or behavior changes, run relevant tests and the strongest `redgate health` mode supported by the installed tool. Do not invent an unsupported `--strict` flag; report a tool/format mismatch explicitly. ## Requirements-first TDD diff --git a/PLAN.md b/PLAN.md index d724a75..d32be8a 100644 --- a/PLAN.md +++ b/PLAN.md @@ -1,19 +1,76 @@ -# hemx plan +# Hemx v1 implementation plan -This is a small work surface for explicitly delegated hemx follow-up. `REQUIREMENTS.md` remains the requirement authority; this file only records execution intent. +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. -## URL-as-state page navigation primitive +## Product boundary -User value: server-first apps can build browse/search/filter pages whose URL is the durable state, so reload, bookmarks, sharing, copy/paste, and back/forward work without app-owned client state or search frameworks. +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. -State: Done +## Slice 1 — one real client-local handler -Build: -- Document the URL-as-state contract for enhanced GET forms and page swaps: native successful controls serialize into the URL; committed submits push history; high-frequency filter typing may replace history; normal reload/no-JS behavior remains native. req: page_swap/009 -- Convert or add one html_examples browse/search example that uses a plain GET form plus generated page/target helpers to prove query-string state round-trips through server-rendered page state. req: page_swap/009 req: htmx_equivalents/005 -- Add focused runtime/browser smoke that changes a GET query, verifies the URL, reloads or uses back/forward, and observes the same rendered state without hidden client state. req: page_swap/005 req: page_swap/009 -- Keep the primitive subtractive: refuse an omnisearch framework, router, selector include model, client state graph, or domain search API in hemx core; use generated forms, page swap, and `Navigate` only. req: page_swap/003 req: page_swap/009 req: page_swap/010 req: htmx_equivalents/003 +- [ ] **User value:** a Rust author marks one high-frequency handler local and gets immediate browser behavior without app-authored JavaScript or a request. +- **State:** Ready. +- **Build:** add the smallest optional `hemx-wasm` boundary for `#[hemx::handler(client)]`; export only opted-in handlers; generate typed event/state ABI glue; run one existing generated-target interaction through the ordinary `EffectBatch` interpreter; 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:** real WASM/browser test visibly updates a generated target, network capture remains empty, invalid event/state restores pending UI with a diagnostic, server handlers are unchanged, and formatting/workspace tests/strict all-target Clippy/wasm-target checks pass. -Blocked by: none. +## Slice 2 — direct manipulation that survives interruption -Proof: `cargo run -p hemx-xtask -- html-examples-smoke`, focused runtime/page-swap tests, `redgate lint`, and `redgate health --strict` pass with an example showing URL state survives reload/back/forward. +- [ ] **User value:** Kanban drag/reorder follows the pointer immediately, remains keyboard operable, and cannot apply stale work after cancellation or root removal. +- **State:** Blocked by Slice 1. +- **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:** browser tests cover pointer and keyboard reorder, cancellation, removal/remount, error recovery, focus/status, reduced motion, zero request, no leaked listeners/timers, and named latency/frame thresholds. + +## 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:** Blocked by Slice 2. +- **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`, `performance/006`. +- **Proof:** browser scenario mutates offline, reloads, restores the projection, exports/deletes/reset data, and fails recoverably under quota, corruption, and unknown schema without claiming durability after persistence failure. + +## Slice 4 — authoritative reconnect and convergence + +- [ ] **User value:** offline and concurrent work reconnects without duplicate mutation, silent loss, stale authorization, or ambiguous conflict. +- **State:** Blocked by Slice 3. +- **Build:** materialize `hemx-sync` over 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`, existing `adapter/*`, `integration/*`, and `diagnostics/*` 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. diff --git a/README.md b/README.md index 02dda51..2e6637d 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,13 @@ handlers, and return generated UI commands. The browser receives checked UI commands; ordinary server-first apps do not need a frontend framework, handwritten UI JavaScript, selector targeting, or raw runtime primitives. req: pitch/001 req: canonical_authoring/001 -Status: the repository currently has a strong v0 example/API path, a compile-tested -SaaS tutorial app, an advanced Kanban milestone sketch, and a full techdemo. -The v1 story now has tutorial, recipe, diagnostics, and stability docs; see -`docs/v1-readiness.md` for the remaining close-gap audit. +Status: the repository has a proven server-first/page-enhanced baseline, a +compile-tested SaaS tutorial, an advanced Kanban sketch, and a full techdemo. +Full v1 is not yet feature-complete: client-local WASM, durable offline/sync, the +production integration reference, and their browser/recovery gates remain active. +See `docs/v1-product-evidence.md` for the evidence-backed product boundary, +`REQUIREMENTS.md` for authority, `PLAN.md` for implementation order, and +`docs/v1-readiness.md` for proven baseline evidence. No publishing is implied. Template authoring: `.heml` is HTML plus a small hemplate overlay for escaped text, trusted HTML, dynamic attributes, Rust-shaped control directives, generated diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index 48c8c8a..9fc9d03 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -690,6 +690,51 @@ what a valid business email is. [north_star] ### req: sync/008 0 008 Sync is bidirectional state reconciliation built on top of push/transport. It is not required for server-sent dashboards, notifications, or live status updates. +### req: sync/009 +0 009 Every queued mutation has a stable client-generated command id, actor/session scope, schema version, and causal ordering token so retries and reconnects do not create ambiguous duplicates. [north_star] + +### req: sync/010 +0 010 The authoritative server processes command ids idempotently and returns an acknowledgement, canonical replacement, explicit rejection, or conflict result; transport success alone never clears local work. [north_star] + +### req: sync/011 +0 011 The client durably advances its acknowledgement cursor only after the corresponding canonical result is committed locally; crash or reload between send and acknowledgement is safe to retry. [north_star] + +### req: sync/012 +0 012 Initial sync uses a versioned snapshot plus an ordered change cursor or an equivalent bounded protocol; reconnect resumes from the last committed cursor and falls back to a fresh snapshot when history is unavailable. [north_star] + +### req: sync/013 +0 013 Server rejection and conflict are distinct outcomes. Each produces application-visible reconciliation data, compensates or replaces optimistic projection explicitly, and never silently drops the command. [north_star] + +### req: sync/014 +0 014 Queued command and projection schema upgrades are transactional and versioned. Incompatible data fails closed with export/reset recovery instead of partial replay. [north_star] + +### req: sync/015 +0 015 Durable browser storage failures, corruption, eviction, and quota exhaustion are observable and recoverable; the adapter must not claim offline durability after persistence fails. [north_star] + +### req: sync/016 +0 016 Reconnect uses bounded exponential backoff with jitter and explicit online/offline state; manual retry remains available, and reconnect storms are prevented. [north_star] + +### req: sync/017 +0 017 Queue size, payload size, in-flight commands, retry rate, and server fan-out are bounded with backpressure and actionable overflow behavior. Unbounded buffering is forbidden. [north_star] + +### req: sync/018 +0 018 Multiple tabs or workers coordinate one durable queue through an explicit lease/ownership protocol or safe idempotent parallel replay; they must not race destructive queue updates. [north_star] + +### req: sync/019 +0 019 Replay revalidates the current authenticated principal, authorization, tenancy, and command preconditions on the server; cached permission from enqueue time is not authority. [north_star] + +### req: sync/020 +0 020 Applications explicitly choose retention, encryption-at-rest, export, and deletion policy for local command data; `hemx-sync` exposes lifecycle hooks but does not invent product policy. [north_star] + +### req: sync/021 +0 021 Sync diagnostics expose queue depth, oldest command age, connection state, retry count, cursor, acknowledgement latency, conflicts, and rejected commands without logging sensitive payloads by default. [north_star] + +### req: sync/022 +0 022 The default reconciliation model is server-authoritative and deterministic for identical snapshot, command sequence, and server results; custom merge or CRDT policy is an explicit integration. [north_star] + +### req: sync/023 +0 023 A durable browser test proves offline mutation, reload, reconnect replay, duplicate delivery, rejection, conflict, schema mismatch, and final convergence through public hemx APIs. [north_star] + --- ## local @@ -947,7 +992,37 @@ what a valid business email is. [north_star] 0 003 High-frequency UI handlers (drag, pointermove, animation tick) must not require server round-trips or handwritten JS. [north_star] ### req: client_local/004 -0 004 Client-local handler opt-in syntax is an integration contract, not hemx-core v0; `hemx-wasm` owns concrete handler attributes. [north_star] +0 004 Client-local handler opt-in syntax is an integration contract, not hemx core; `hemx-wasm` owns `#[hemx::handler(client)]` and its browser boundary. [north_star] + +### req: client_local/005 +0 005 A client-local handler accepts generated events and explicit state and returns the same `IntoEffect`/`EffectBatch` contract as a server handler; it must not expose DOM mutation APIs. [north_star] + +### req: client_local/006 +0 006 `hemx-wasm` exports only handlers explicitly opted into client execution and rejects parameters, captures, or return values that cannot cross its generated ABI with an actionable Rust span. [north_star] + +### req: client_local/007 +0 007 Each hemx root owns its client-local state instance; initialization from defaults or versioned `data-hemx-st` input is explicit, and no process-global browser singleton owns application state. [north_star] + +### req: client_local/008 +0 008 Invalid browser event payload or incompatible bootstrap state must not call the handler; the runtime emits a root-scoped diagnostic, restores pending UI, and preserves a native/server fallback where declared. [north_star] + +### req: client_local/009 +0 009 A successfully dispatched client-local handler applies its ordinary `EffectBatch` through the same version/fingerprint checks and ordered root-scoped effect interpreter used for server responses. [north_star] + +### req: client_local/010 +0 010 A client-local interaction performs no network request unless the handler explicitly returns an integration effect that declares remote work. [north_star] + +### req: client_local/011 +0 011 Client-local handlers are cancellable or supersedable according to the generated handle policy, and stale asynchronous completions must not overwrite newer state or effects. [north_star] + +### req: client_local/012 +0 012 Removing a hemx root releases its handler bindings, timers, observers, pending work, and local state; repeated mount/unmount must not leak root-owned browser resources. [north_star] + +### req: client_local/013 +0 013 Direct-manipulation client handlers meet an evidence-backed interaction budget: ordinary input responds within 100 ms, and pointer-follow animation work fits the tested frame budget on the supported baseline browser. [north_star] + +### req: client_local/014 +0 014 Client-local behavior has a browser-level proof using generated resources, a real WASM artifact, zero app-authored JavaScript, and network instrumentation that distinguishes local from server execution. [north_star] --- @@ -1272,6 +1347,146 @@ async fn delete(app: State, todo_id: TodoId) -> impl IntoEffect --- +## accessibility + +### req: accessibility/001 +0 001 Server-first, page-enhanced, client-local, and sync modes preserve semantic HTML and native link/form behavior; enhancement must not remove an available keyboard or no-script path. [north_star] + +### req: accessibility/002 +0 002 Every generated interaction is keyboard operable. Pointer-specific features such as drag/drop provide an application-declared keyboard action path with equivalent outcome. [north_star] + +### req: accessibility/003 +0 003 Effect application preserves or deliberately moves focus. Removed focused nodes, validation failures, modal boundaries, navigation, and full-page fallback each have deterministic focus behavior. [north_star] + +### req: accessibility/004 +0 004 Pending, success, validation, transport, offline, conflict, and recovery state is exposed programmatically through native validity, `aria-busy`, status/error regions, or generated application targets without relying on color or motion alone. [north_star] + +### req: accessibility/005 +0 005 Generated resources preserve authored accessible names, roles, values, labels, descriptions, and table/list structure across replacement, insertion, and reconciliation. [north_star] + +### req: accessibility/006 +0 006 Optional transitions and direct-manipulation effects honor reduced-motion preferences and do not block input, focus, or recovery when animation is disabled. [north_star] + +### req: accessibility/007 +0 007 The supported example matrix includes automated accessibility checks plus keyboard/focus browser scenarios for forms, page navigation, client-local interaction, offline state, and error recovery. [north_star] + +--- + +## operations + +### req: operations/001 +0 001 Every request, push stream, client-local dispatch, sync command, acknowledgement, and effect application has a stable correlation boundary that integrations can attach to existing tracing without hemx owning a telemetry backend. [north_star] + +### req: operations/002 +0 002 Integration diagnostics distinguish build/version mismatch, transport failure, timeout, cancellation, decode failure, missing target, handler rejection, authorization denial, storage failure, and sync conflict. [north_star] + +### req: operations/003 +0 003 Requests, streams, handlers, and background replay support explicit timeouts and cancellation; cancellation restores pending UI and prevents late effects from applying. [north_star] + +### req: operations/004 +0 004 Push and sync adapters implement bounded buffering, heartbeat/liveness detection, reconnect backoff, and slow-consumer behavior instead of relying on unbounded transport queues. [north_star] + +### req: operations/005 +0 005 Production diagnostics omit sensitive form values, auth material, local command payloads, and rendered private HTML by default; development detail is explicit and cannot silently enable in production. [north_star] + +### req: operations/006 +0 006 Mixed deploy versions fail closed through ABI/fingerprint checks and recover by reload, full navigation, or fresh sync snapshot; rolling deployment must not apply an incompatible partial batch. [north_star] + +### req: operations/007 +0 007 A production reference exposes health/readiness, structured errors, tracing hooks, and metrics for latency, failures, queue pressure, reconnect, and effect decode/apply without requiring a hemx-specific observability stack. [north_star] + +### req: operations/008 +0 008 Process restart, browser reload, network interruption, duplicate delivery, and partial deployment are first-class recovery tests rather than manual release notes. [north_star] + +--- + +## security + +### req: security/001 +0 001 Hemx-owned HTML and attribute sinks preserve hemplate escaping and explicit `SafeHtml` trust boundaries in every execution mode; sync, WASM, and push must not introduce a weaker payload path. [north_star] + +### req: security/002 +0 002 Standard HTTP, navigation, asset, push, and sync connections are same-origin by default. Cross-origin use requires explicit integration configuration and cannot silently forward credentials. [north_star] + +### req: security/003 +0 003 Mutating HTTP integrations expose testable origin/CSRF enforcement, secure session/cookie boundaries, request-size limits, and content-type validation while leaving application policy to the host framework. [north_star] + +### req: security/004 +0 004 Every handler invocation and replayed command receives current authenticated identity and authorization context from the integration boundary; numeric generated ids are routing identifiers, never authorization. [north_star] + +### req: security/005 +0 005 Effect, state, event, command, and sync decoders reject unknown versions, invalid kinds, oversized lengths, truncated values, and trailing incompatible data without panicking or partially applying the batch. [north_star] + +### req: security/006 +0 006 The browser runtime and generated bootstrap are compatible with a strict Content Security Policy: no `eval`, dynamic code generation, inline application script requirement, or `javascript:` URL. [north_star] + +### req: security/007 +0 007 Local persistence makes sensitive-data exposure explicit: applications can redact, encrypt, expire, export, and delete queued data, and examples never store credentials or session secrets in offline command records. [north_star] + +### req: security/008 +0 008 Release evidence includes a pinned advisory audit of the committed lockfile, review of unsafe code and licenses, and documented disposition for every accepted advisory or supply-chain exception. [north_star] + +### req: security/009 +0 009 Hemx claims only the framework controls it proves. Application compliance, identity provider, database encryption, backup, retention, and incident policy remain explicit host responsibilities. [north_star] + +--- + +## performance + +### req: performance/001 +0 001 Performance requirements are measured on named supported configurations with reproducible fixtures; “fast”, “60fps”, and bundle-size claims must have commands, baselines, and regression thresholds. [north_star] + +### req: performance/002 +0 002 Server-first and page-enhanced handlers add bounded framework overhead relative to rendering and transport, and benchmark regressions fail the repository performance gate. [north_star] + +### req: performance/003 +0 003 Client-local direct manipulation responds within 100 ms for ordinary input and keeps pointer-follow work within the tested frame budget without network dependence. [north_star] + +### req: performance/004 +0 004 Initial sync is proportional to the scoped snapshot, incremental sync is proportional to delivered changes, and neither path requires loading unrelated workspace state. [north_star] + +### req: performance/005 +0 005 Effect decode/apply, generated target lookup, queue replay, and keyed reconciliation have adversarial size tests and explicit memory/operation bounds. [north_star] + +### req: performance/006 +0 006 Optional WASM, sync, PWA, transition, and editor assets are separately loadable; server-first applications do not pay their download, initialization, or dependency cost. [north_star] + +--- + +## v1_release + +### req: v1_release/001 +0 001 Hemx v1 is feature-complete only when server-first, page-enhanced, client-local WASM, and hybrid offline/sync modes share generated resources and `EffectBatch` semantics and pass their end-to-end proof scenarios. [north_star] + +### req: v1_release/002 +0 002 The local-first multiplayer Kanban milestone proves direct manipulation, optimistic projection, offline durability, reload, ordered replay, idempotency, conflict/rejection, presence, convergence, and SSR-first fallback without React, Vue, VDOM, or app-authored JavaScript. [north_star] + +### req: v1_release/003 +0 003 A production reference proves durable persistence, current authorization, CSRF/origin policy, transactions, restart recovery, structured failures, observability hooks, accessibility, and deploy compatibility while keeping vendor policy outside hemx core. [north_star] + +### req: v1_release/004 +0 004 Public Rust API, generated API, Surface schema, symbol schema, wire ABI, browser runtime ABI, persisted sync schema, MSRV, and supported browser changes each have an explicit compatibility and migration policy. [north_star] + +### req: v1_release/005 +0 005 V1 documentation teaches one progression: server-first partial swaps, page enhancement, explicit islands/client-local handlers, then durable sync; every level states ownership, failure, recovery, accessibility, security, and operational boundaries. [north_star] + +### req: v1_release/006 +0 006 Release closure requires formatting, workspace tests, strict all-target linting, compile-fail contracts, browser/WASM/offline scenarios, performance budgets, security audit, documentation checks, examples, and clean-tree reproducibility with no unresolved P0 or P1 defect. [north_star] + +### req: v1_release/007 +0 007 The supported matrix names Rust/MSRV, browser versions, WASM target/toolchain, operating systems needed for development, and integration crate versions; unsupported combinations fail with actionable diagnostics. [north_star] + +### req: v1_release/008 +0 008 All canonical examples use public generated APIs and are treated as compatibility tests. No release claim depends on unpublished demo-only glue, ad hoc scripts, or test-only runtime behavior. [north_star] + +### req: v1_release/009 +0 009 Local release-readiness validation must not publish crates, deploy services, upload artifacts, submit stores, or mutate external systems. Publishing remains a separate explicit human-authorized action. [north_star] + +### req: v1_release/010 +0 010 Feature-complete does not mean feature-accumulative: v1 refuses a built-in router, auth system, database, mandatory client store, default CRDT, component lifecycle, VDOM, selector language, telemetry vendor, deployment platform, and application policy framework. [north_star] + +--- + ## multipart ### req: multipart/001 diff --git a/docs/v1-product-evidence.md b/docs/v1-product-evidence.md new file mode 100644 index 0000000..5b0ab94 --- /dev/null +++ b/docs/v1-product-evidence.md @@ -0,0 +1,166 @@ +# Hemx v1 product evidence + +This document records external evidence used to sharpen the hemx v1 requirements. +It is not authority over `REQUIREMENTS.md`, and precedent does not prove demand. +The product decision remains: checked hypermedia for Rust, with server-first as the +simple default and client-local/offline execution as explicit opt-in layers over +the same generated-resource and effect contract. + +Research checked on 2026-07-13. + +## User job and alternatives + +The target user is a Rust team building an interaction-heavy web application that +wants server-rendered HTML and ordinary Rust domain logic without accepting a +second selector/string contract or a component/VDOM runtime. Today that team can: + +- use server-only hypermedia and accept round-trip latency; +- add handwritten JavaScript and own two state/effect models; +- adopt React/Vue or another client framework for local interaction; +- use LiveView/Turbo-style server-driven interaction; or +- build a local-first sync engine directly. + +Those alternatives work. Hemx v1 is justified only if execution location can be +an opt-in handler choice while generated resources, `EffectBatch`, failure +semantics, and server authority stay coherent. + +## Evidence and decisions + +### Linear: local responsiveness requires a real sync architecture + +Sources: + +- [Scaling the Linear Sync Engine](https://linear.app/now/scaling-the-linear-sync-engine) +- [Linear Method](https://linear.app/method/introduction) +- [Linear Security](https://linear.app/security) +- [How Linear uses Google Cloud databases](https://cloud.google.com/blog/products/databases/product-workflow-tool-linear-uses-google-cloud-databases) + +Linear materializes fast local interaction with a client-side data model and a +server replication/sync system rather than hiding latency behind cosmetic +loading states. Its published architecture discusses initial synchronization, +real-time updates, database change capture, and scaling work; its product method +also values deliberate, opinionated workflows. Its security page treats access, +encryption, backups, monitoring, incident handling, and independent assurance as +operational systems rather than UI features. + +**Use in hemx:** client-local work must be genuinely local; offline/sync must have +durable identities, bounded queues, resumable acknowledgement, migration, +conflict/rejection behavior, and observable recovery. Production proof must cover +operations and failures, not only the happy-path API. + +**Do not copy:** hemx is a framework, not Linear's product. It must not grow issue +tracking, workspace policy, SSO/SCIM, a hosted database, or a mandatory global +client graph. Authentication, authorization, encryption policy, backups, and +retention remain application/platform concerns; hemx integrations must expose +boundaries that let applications enforce and test them. + +### Local-first: offline is a data-ownership and recovery promise + +Source: [Local-first software: You own your data, in spite of the cloud](https://www.inkandswitch.com/essay/local-first/). + +The local-first work identifies availability without a network, multi-device +coordination, ownership, longevity, and collaboration as distinct properties. A +cache or optimistic DOM patch does not establish them. + +**Use in hemx:** persisted commands/domain events are truth; DOM effects are +projections. Queue durability, export/deletion, schema upgrades, conflict policy, +and recovery from corruption/quota failure must be explicit. “Offline capable” +cannot mean only that a shell loads. + +**Do not copy:** CRDTs are not the default. Hemx v1 keeps the server authoritative +and requires explicit opt-in policy where collaboration semantics differ. + +### Hypermedia and live-server systems: preserve browser and deploy semantics + +Sources: + +- [HTMX documentation](https://htmx.org/docs/) +- [Phoenix LiveView deployments](https://hexdocs.pm/phoenix_live_view/deployments.html) +- [Turbo Handbook](https://turbo.hotwired.dev/handbook/introduction) + +These systems demonstrate progressive enhancement, history-aware navigation, +request synchronization, server-driven DOM updates, reconnect/deployment +concerns, and the value of preserving ordinary links and forms. + +**Use in hemx:** real `href`/form fallback, back/forward correctness, stale-request +suppression, deploy fingerprint refusal, reconnect behavior, and clear full-page +recovery are release requirements. + +**Do not copy:** selector mini-languages, implicit component lifecycles, and a +router owned by core remain outside hemx. + +### Platform primitives: use the browser's durable and accessible contracts + +Sources: + +- [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) +- [Using Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers) +- [WCAG 2.2 quick reference](https://www.w3.org/WAI/WCAG22/quickref/) +- [RAIL performance model](https://web.dev/articles/rail) + +IndexedDB provides transactional browser storage; service workers provide an +HTTPS-bound offline/network interception lifecycle. WCAG 2.2 makes keyboard +operation, visible focus, status/error communication, and programmatic +name/role/value release concerns. RAIL treats roughly 100 ms as the response +window in which direct manipulation feels immediate. + +**Use in hemx:** optional adapters reuse platform storage/service-worker +primitives; storage failures and upgrades are recoverable. Generated interaction +must preserve semantic HTML, keyboard operation, focus, status/error +announcements, and reduced-motion preferences. Client-local interaction gets an +observable latency/frame budget rather than a “fast” adjective. + +**Do not copy:** hemx core does not mandate IndexedDB, a service worker, or an +application cache policy. + +### Security and release discipline: framework controls need testable boundaries + +Sources: + +- [OWASP Application Security Verification Standard 5.0](https://owasp.org/www-project-application-security-verification-standard/) +- [Cargo SemVer compatibility](https://doc.rust-lang.org/cargo/reference/semver.html) +- [cargo-audit](https://github.com/rust-secure-code/cargo-audit) + +ASVS provides a test-oriented baseline for web controls such as encoding, +injection prevention, session/access boundaries, validation, and logging. Cargo's +SemVer guidance shows that public Rust items, traits, features, MSRV, and runtime +behavior all carry compatibility risk. `cargo-audit` checks the committed lockfile +against RustSec advisories. + +**Use in hemx:** unsafe HTML stays type-gated; integrations make origin/CSRF, +authorization, limits, and security logging testable; replay never bypasses +current authorization. v1 has an explicit public/generated/wire/runtime +compatibility policy, migration evidence, MSRV/browser support, and a pinned +lockfile advisory audit before release approval. + +**Do not copy:** hemx does not claim application-level ASVS compliance. It proves +only controls and boundaries it owns. Publishing remains a separate explicit +human decision. + +## Product thesis + +Hemx v1 should feel like boring server-rendered HTML with typed, selectorless +partial swaps, while letting a team opt one handler into local WASM or durable +sync without changing the resource/effect language. The smallest coherent +mechanism is: + +1. hemplate Surface facts and generated resources; +2. one handler shape with explicit execution placement; +3. one versioned `EffectBatch` application contract; +4. server-first by default; +5. explicit local state ownership; +6. optional durable command-log/reconciliation adapters; and +7. fail-closed versioning plus native-browser recovery. + +## Kill tests + +Reshape or drop client-local/sync work if any slice requires: + +- a second effect protocol or selector target language; +- hidden global state or a component lifecycle; +- bespoke JavaScript per application handler; +- persisted DOM/effect payloads as domain truth; +- a mandatory browser database, service worker, CRDT, or conflict policy; +- authorization decisions cached across replay without server revalidation; or +- inaccessible interaction or failure states that cannot preserve native HTML + fallback. diff --git a/docs/v1-readiness.md b/docs/v1-readiness.md index 294984d..f28e8e2 100644 --- a/docs/v1-readiness.md +++ b/docs/v1-readiness.md @@ -1,10 +1,22 @@ # v1 readiness audit -This audit records the current hemx v1 northstar against the active Close when. -It is not a marketing release announcement; it is the engineering closure record -for the current v1 product-readiness goal. req: examples/001 req: public_api/001 +This audit records the proven server-first/page-enhanced baseline. It is not a +marketing release announcement and no longer claims the full v1 north star is +closed. The product evidence in `docs/v1-product-evidence.md` and current +requirements add client-local WASM, durable offline/sync, accessibility, +security, operations, performance, compatibility, and production-reference +closure. Their implementation order lives in `PLAN.md`. req: examples/001 req: public_api/001 req: v1_release/001 -## Close-when status +## Current status + +- Server-first and page-enhanced baseline: proven by the evidence below. +- Client-local WASM: not implemented; first active v1 slice. +- Durable offline/sync: contracts shaped, implementation blocked by the local + execution boundary. +- Full production reference and v1 closure matrix: not yet proven. +- Publishing and deployment: explicitly unauthorized. + +## Baseline evidence ### Canonical tutorial app @@ -141,6 +153,11 @@ Evidence: ## Final closure gates +The following baseline commands remain required. They are insufficient for full +v1 closure until the browser/WASM/offline/multiplayer, accessibility, security, +performance, compatibility, and production-reference proofs in `v1_release/*` +also pass. Run them only as local validation; none publishes or deploys. + Run these on the final tree before GOAL_DONE: ```sh