diff --git a/AGENTS.md b/AGENTS.md index 2e11548..71e21c1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -58,7 +58,7 @@ Keep it stable. Prefer pointers to canonical sources over copied structure, file - The public component-reuse explanation lives in `docs/recipes/reusable-partials.md`; do not grow a client component framework to explain partial composition. - The stable public `.heml` authoring surface lives in `docs/hemplate-syntax.md`; Hemlate examples must use that real hemplate syntax, not Vue/Handlebars sketches. - 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, fail-closed request handling, and tiny pending/failure recovery without selectors, VDOM, expressions, or per-node listeners. req: runtime/005 req: convention/007 +- JS runtime changes must preserve root-scoped lookup, fail-closed request handling, root-scoped error outlets, and tiny pending/failure recovery without selectors, VDOM, expressions, or per-node listeners. req: runtime/005 req: convention/007 - Host capability adapters must stay at the `hemx-host` boundary: they may call host APIs and return host events, but they must not mutate DOM or own app/domain state. req: host/002 - Local/offline app behavior should be commands/events/projections; do not add `hemx-local`, stored DOM patches, or stored `EffectBatch` truth without a proven reusable contract. req: local/001 req: local/002 - 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. diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index 7b676ab..72fd506 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -448,7 +448,7 @@ what a valid business email is. 004 Core runtime exposes a minimal version/fingerprint handshake only. Capability negotiation belongs to integration crates such as `hemx-wasm`, `hemx-sync`, and `hemx-transition`. ### req: runtime/005 -005 Failed hemx HTTP requests must fail closed: non-2xx responses are not applied as effects, pending state is restored, and the runtime emits an inspectable `hemx:error` event with status when available. [north_star] +005 Failed hemx HTTP requests must fail closed: non-2xx responses are not applied as effects, pending state is restored, root-scoped `data-hemx-error` outlets show a transport failure when present, and the runtime emits an inspectable `hemx:error` event with status when available. [north_star] --- diff --git a/examples/v0/src/main.rs b/examples/v0/src/main.rs index 1938f82..47d8137 100644 --- a/examples/v0/src/main.rs +++ b/examples/v0/src/main.rs @@ -133,7 +133,7 @@ impl Hemplate for Todos { fn render_into(&self, buf: &mut String) -> Result<(), hemplate::error::HemplateError> { use std::fmt::Write as _; - buf.push_str("
\n
\n \n \n

\n
\n\n

"); + buf.push_str("

\n
\n \n \n

\n
\n\n \n\n

"); write!(buf, "{}", hemplate::HtmlEscape(&self.summary))?; buf.push_str("

\n

"); write!(buf, "{}", hemplate::HtmlEscape(&self.notice))?; @@ -627,6 +627,11 @@ mod tests { 2, "add and rename forms expose generated field-error targets" ); + assert_eq!( + document.select(&selector("[data-hemx-error]")).count(), + 1, + "the app exposes one root-scoped transport error outlet" + ); } // req: canonical_authoring/003 req: test/005 diff --git a/examples/v0/templates/todos.heml b/examples/v0/templates/todos.heml index a66ea91..cb5b730 100644 --- a/examples/v0/templates/todos.heml +++ b/examples/v0/templates/todos.heml @@ -4,6 +4,7 @@

+

{+ self.summary +}

{+ self.notice +}