docs(requirements): split interop ownership rows

Add explicit northstar ring fields to interop requirements, split leaf/preserve/no-framework boundaries, and shorten ownership wording without changing behavior.

req: interop/001

req: interop/002

req: interop/003

req: interop/004

req: interop/005

req: interop/006

req: interop/007

req: interop/008

req: interop/009

req: interop/010

req: interop/011

req: interop/012
This commit is contained in:
slhx agent
2026-06-25 15:57:58 +02:00
parent 0337a44edb
commit 11e50ab647
2 changed files with 21 additions and 9 deletions
+1 -1
View File
@@ -65,7 +65,7 @@ Keep it stable. Prefer pointers to canonical sources over copied structure, file
- The stable public `.heml` authoring surface lives in `docs/hemplate-syntax.md`; Hemlate examples must use that real hemplate syntax, not Vue/Handlebars sketches. hemx-build consumes hemplate Surface facts and must not grow an independent `.heml` parser or CSS-path identity model. Generated resources, form/handle metadata, atoms, and event constants come from hemx-build facts, not hand-written app plumbing. Forms remain HTML-shaped, checked against user-authored Rust domain types, parsed through `FormValue`, and manipulated through generated form/control ids rather than selectors. req: surface/001 req: surface/002 req: surface/003 req: surface/004 req: surface/005 req: surface/006 req: surface/007 req: surface/008 req: surface/009 req: surface/010 req: codegen/001 req: codegen/003 req: codegen/004 req: codegen/005 req: codegen/006 req: form/001 req: form/004 req: form/007 req: form/008 req: form_effects/001 req: form_effects/002 req: form_effects/003 - The stable public `.heml` authoring surface lives in `docs/hemplate-syntax.md`; Hemlate examples must use that real hemplate syntax, not Vue/Handlebars sketches. hemx-build consumes hemplate Surface facts and must not grow an independent `.heml` parser or CSS-path identity model. Generated resources, form/handle metadata, atoms, and event constants come from hemx-build facts, not hand-written app plumbing. Forms remain HTML-shaped, checked against user-authored Rust domain types, parsed through `FormValue`, and manipulated through generated form/control ids rather than selectors. req: surface/001 req: surface/002 req: surface/003 req: surface/004 req: surface/005 req: surface/006 req: surface/007 req: surface/008 req: surface/009 req: surface/010 req: codegen/001 req: codegen/003 req: codegen/004 req: codegen/005 req: codegen/006 req: form/001 req: form/004 req: form/007 req: form/008 req: form_effects/001 req: form_effects/002 req: form_effects/003
- Optional `.heml` editor overlays must share authority with `hemx-build` diagnostics and `docs/hemplate-syntax.md`; `hemx-lsp` owns editor protocol glue for diagnostics/completion/hover and derive-known template facts, while VS Code/Cursor/Neovim keep normal HTML/tree-sitter tooling. Do not create a second template language, selector model, formatter, Rust type system, or custom editor framework. req: diagnostics/004 req: diagnostics/005 req: diagnostics/006 - Optional `.heml` editor overlays must share authority with `hemx-build` diagnostics and `docs/hemplate-syntax.md`; `hemx-lsp` owns editor protocol glue for diagnostics/completion/hover and derive-known template facts, while VS Code/Cursor/Neovim keep normal HTML/tree-sitter tooling. Do not create a second template language, selector model, formatter, Rust type system, or custom editor framework. req: diagnostics/004 req: diagnostics/005 req: diagnostics/006
- JS runtime changes must preserve root-scoped lookup, delegated listeners, postcard EffectBatch application, fail-closed request handling, transactional/recoverable failure behavior, root-scoped error outlets, and tiny pending/failure/trigger-timing conventions without selectors, VDOM, expressions, or per-node listeners. req: runtime/001 req: runtime/002 req: runtime/003 req: runtime/005 req: runtime/006 req: failure/001 req: failure/002 req: failure/003 req: failure/004 req: failure/005 req: failure/006 req: convention/001 req: convention/003 req: convention/005 req: convention/007 - JS runtime changes must preserve root-scoped lookup, delegated listeners, postcard EffectBatch application, fail-closed request handling, transactional/recoverable failure behavior, root-scoped error outlets, and tiny pending/failure/trigger-timing conventions without selectors, VDOM, expressions, or per-node listeners. req: runtime/001 req: runtime/002 req: runtime/003 req: runtime/005 req: runtime/006 req: failure/001 req: failure/002 req: failure/003 req: failure/004 req: failure/005 req: failure/006 req: convention/001 req: convention/003 req: convention/005 req: convention/007
- Opaque island JavaScript is a leaf adapter for high-frequency local behavior only; it must not introduce a component runtime, client state graph, VDOM, or second UI model. req: canonical_authoring/017 - Opaque island JavaScript is a leaf adapter for high-frequency local behavior only; use native events/generated helpers at the boundary and do not introduce a component runtime, client state graph, VDOM, selector interop, or second UI model. req: canonical_authoring/017 req: interop/001 req: interop/002 req: interop/003 req: interop/006 req: interop/007 req: interop/008 req: interop/009 req: interop/010 req: interop/011 req: interop/012
- Host capability adapters must stay at the `hemx-host` boundary: typed capabilities use fire/request/stream/schedule shapes; adapters may call host APIs and return host events, but they must not mutate DOM or own app/domain state. req: host/001 req: host/002 - Host capability adapters must stay at the `hemx-host` boundary: typed capabilities use fire/request/stream/schedule shapes; adapters may call host APIs and return host events, but they must not mutate DOM or own app/domain state. req: host/001 req: host/002
- Local/offline app behavior should be commands/events/projections; do not add `hemx-local`, stored DOM patches, stored `EffectBatch` truth, or a core client state graph without a proven reusable contract. Replay, reconciliation, export, and deletion rules stay explicit product decisions, and exemplars should show UI effects as app-state output. req: canonical_authoring/018 req: canonical_authoring/019 req: local/001 req: local/002 req: local/003 req: local/004 - Local/offline app behavior should be commands/events/projections; do not add `hemx-local`, stored DOM patches, stored `EffectBatch` truth, or a core client state graph without a proven reusable contract. Replay, reconciliation, export, and deletion rules stay explicit product decisions, and exemplars should show UI effects as app-state output. req: canonical_authoring/018 req: canonical_authoring/019 req: local/001 req: local/002 req: local/003 req: local/004
- Axum apps should serve and load the shared runtime through hemx-axum helpers such as `runtime_js_path()` and `runtime_js()`, not hard-coded `/hemx.js` URLs or app-owned cache-busting strings; keep hemx-axum as route/runtime/handler adapter around generated partial swaps, not a routing owner. req: axum_integration/001 req: axum_integration/002 req: axum_integration/003 req: axum_integration/005 req: axum_integration/006 - Axum apps should serve and load the shared runtime through hemx-axum helpers such as `runtime_js_path()` and `runtime_js()`, not hard-coded `/hemx.js` URLs or app-owned cache-busting strings; keep hemx-axum as route/runtime/handler adapter around generated partial swaps, not a routing owner. req: axum_integration/001 req: axum_integration/002 req: axum_integration/003 req: axum_integration/005 req: axum_integration/006
+20 -8
View File
@@ -699,28 +699,40 @@ what a valid business email is. [north_star]
## interop ## interop
### req: interop/001 ### req: interop/001
001 `Effect::event` and generated event helpers are the single hemx-to-widget bridge. External widgets, charts, games, maps, Alpine/Svelte islands, and Web Components listen via native `CustomEvent`; hemx core does not inspect their state, rendering internals, or framework lifecycle. [north_star] 0 001 `Effect::event` and generated event helpers are the single hemx-to-widget bridge. Widgets, charts, games, maps, Alpine/Svelte islands, and Web Components listen via native `CustomEvent`; hemx core does not inspect their state or lifecycle. [north_star]
### req: interop/002 ### req: interop/002
002 Web Components and custom elements are valid opaque leaf nodes. hemx does not inspect shadow DOM or mutate inside custom elements unless the author explicitly exposes hemx-owned slots/handles at the boundary. Escape hatches are leaves, never app foundations. 0 002 Web Components and custom elements are valid opaque leaf nodes. hemx does not inspect shadow DOM or mutate inside custom elements unless the author explicitly exposes hemx-owned slots/handles at the boundary. [north_star]
### req: interop/009
0 009 Escape hatches are leaves, never app foundations. [north_star]
### req: interop/003 ### req: interop/003
003 WASM islands and third-party framework islands are explicit leaf boundaries. hemx may replace the island root as a generated target, but it does not manage inside it; hemx owns the generated slot/island boundary, Alpine/Svelte/Web Components/hand-written widgets own the inside, and events cross the boundary. Commands flow widget-to-hemx through explicit generated handles or `hemx.send(...)`, and server-to-widget through generated event helpers such as `ui::chart.emit(snapshot)`. 0 003 WASM islands and third-party framework islands are explicit leaf boundaries. hemx may replace the island root as a generated target, but it does not manage inside it. [north_star]
### req: interop/010
0 010 hemx owns generated slot/island boundaries; widgets own the inside, and events cross the boundary. Commands flow widget-to-hemx through generated handles or `hemx.send(...)`; server-to-widget through helpers like `ui::chart.emit(snapshot)`. [north_star]
### req: interop/004 ### req: interop/004
004 Existing `hx-*` attributes are treated as ordinary raw attributes in the hemplate Surface without hemx semantics. An optional `hemx-htmx-migrate` tool may read Surface `hx-*` attrs and suggest equivalent `data-hemx-*` handlers/effects. 0 004 Existing `hx-*` attributes are treated as ordinary raw attributes in the hemplate Surface without hemx semantics. An optional `hemx-htmx-migrate` tool may read Surface `hx-*` attrs and suggest equivalent `data-hemx-*` handlers/effects. [north_star]
### req: interop/005 ### req: interop/005
005 HTMX-style response triggers and widget notifications are represented by `Effect::event` or generated event helpers. Events are native `CustomEvent`s scoped to the hemx root. 0 005 HTMX-style response triggers and widget notifications are represented by `Effect::event` or generated event helpers. Events are native `CustomEvent`s scoped to the hemx root. [north_star]
### req: interop/006 ### req: interop/006
006 `data-hemx-preserve` is an explicit preserve boundary for rare leaf-widget cases where hemx updates around a subtree without destroying it. Preserve semantics must be simple: preserve the marked subtree identity, do not diff or hydrate inside it, and require authors to mark the boundary deliberately. Preserve must not become a default lifecycle model or a workaround for unclear ownership. 0 006 `data-hemx-preserve` is an explicit preserve boundary for rare leaf-widget cases where hemx updates around a subtree without destroying it. Preserve the marked subtree identity; do not diff or hydrate inside it. [north_star]
### req: interop/011
0 011 Preserve boundaries require deliberate author marks. Preserve must not become a default lifecycle model or a workaround for unclear ownership. [north_star]
### req: interop/007 ### req: interop/007
007 The runtime emits native lifecycle events such as `hemx:before-swap`, `hemx:after-swap`, `hemx:event`, `hemx:connect`, and `hemx:disconnect` so Alpine, Svelte, Web Components, and hand-written widgets can attach at DOM/event boundaries. hemx core must not add framework-specific adapters. 0 007 The runtime emits native lifecycle events such as `hemx:before-swap`, `hemx:after-swap`, `hemx:event`, `hemx:connect`, and `hemx:disconnect` so widgets can attach at DOM/event boundaries. hemx core must not add framework-specific adapters. [north_star]
### req: interop/008 ### req: interop/008
008 Interop must prevent selector hacks, manual JS reinitialization races, lost widget state after swaps, and double-owned state by making ownership explicit: hemx owns generated server DOM targets, the external widget owns explicit leaves, and events are the supported crossing point. Core must not add selector targeting, hydration compatibility, a client store, or a framework lifecycle to make interop easy. 0 008 Interop prevents selector hacks, JS reinitialization races, lost widget state, and double-owned state through explicit ownership: hemx owns generated server DOM targets, widgets own leaves, and events are the crossing point. [north_star]
### req: interop/012
0 012 Core must not add selector targeting, hydration compatibility, a client store, or a framework lifecycle to make interop easy. [north_star]
--- ---