diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..809a21f
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,30 @@
+# Working in OctoScript-Makepad
+
+Read [README.md](README.md) and the
+[code walkthrough](docs/architecture-walkthrough.md) before changing the runtime.
+
+- This repository owns portable UI nodes, checked DSL evaluation, Makepad
+ translation, native themed widgets and preview/catalog hosts. App installation,
+ persistent app stores and system/app agents belong to consuming hosts.
+- `runtime.json` and root `Cargo.toml` select the source set. Keep Makepad and
+ OctoScript pins consistent, preserve one Makepad instance per resolved graph,
+ and do not move a consumer's dependency pin as an incidental fix.
+- `octoscript-node` deliberately has no dependencies. Keep its portable boundary
+ free of VM, platform and agent dependencies.
+- Trace L0 realization, native kit lowering and measured-design translation
+ separately. Preserve whole-tree failure for malformed or budget-exhausted
+ input in `octoscript_render::build`. The final widget-source evaluation uses
+ `eval_checked` in beauty-host, but `eval_with_append_source` in kit-host;
+ keep their budget descriptions distinct.
+- The current `kit-host` and `beauty-host` mount a `View` evaluated on the main
+ VM into `Splash.view`.
+- Keep UI state, app persistence and agent memory distinct in code and docs.
+ Capabilities exist only when a host supplies them. A preview is not a
+ production app service or an agent permission grant.
+- For render changes run appropriate portable tests, normally
+ `cargo test --release -p octoscript-node -p octoscript-render -p octoscript-makepad`.
+ Widget/layout changes also need native acceptance with `beauty-host --remote`;
+ use actual measurements and screenshots. If you could not run the native
+ check, say so in the PR.
+- Keep English and Chinese README architecture/build claims consistent. Use
+ source links and keep operational instructions separate from PR validation notes.
diff --git a/README.md b/README.md
index 0730375..d28880b 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,30 @@
-# Octoscript-Makepad
+# OctoScript-Makepad
English | [简体中文](README.zh-CN.md)
> **Building an OctoSense app?** You do not need to work in this repository. It is the shared UI runtime every OctoSense shell and `card-host` build against; `tools/setup-native.py` in OctoScript-App-Design-Flow checks it out for you as the sibling `octoscript-makepad/` at the pinned revision. Start from the [OctoSense organization profile](https://github.com/OctoSense-org)'s reading order: [OctoScript-App-Design-Flow `AGENTS.md`](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/AGENTS.md) → [`flows/README.md`](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/flows/README.md) → [`docs/QUICKSTART.md`](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/docs/QUICKSTART.md).
-Themed, cross-platform **component kits** for apps built on the **Octoscript DSL → makepad native-widget** renderer.
+Themed, cross-platform **component kits** for apps built on the **OctoScript DSL → makepad native-widget** renderer.
-Author a UI once as plain-data Octoscript DSL; it is evaluated in the makepad-script VM, translated to makepad's own widget dialect, and mounted as **real native makepad widgets** at runtime (with on-device hot reload). This repo is the home for the render pipeline **and** the themed component sets that ride on it — Material 3 today; **iOS** and **liquid-glass** planned.
+Author a UI once as plain-data OctoScript DSL; it is evaluated in the makepad-script VM, translated to makepad's own widget dialect, and mounted as **real native makepad widgets** at runtime (with on-device hot reload). This repo is the home for the render pipeline **and** the themed component sets that ride on it — Material 3 today; **iOS** and **liquid-glass** planned.
+
+Follow a text label from source to native widgets in the
+[code walkthrough](docs/architecture-walkthrough.md), then explore L0 cards,
+preview commands, state and agent boundaries. Contributor guidance is in
+[AGENTS.md](AGENTS.md).
## The pipeline
```
-Octoscript DSL ──► octoscript-render ──► UiNode tree ──► octoscript-makepad ──► makepad dialect string
+OctoScript DSL ──► octoscript-render ──► UiNode tree ──► octoscript-makepad ──► makepad dialect string
{t:"column", (makepad-script VM, (backend- (pure translation) View{…}/Label{…}/…
c:[ … ]} renderer-free) agnostic) │
▼
- makepad `Splash` widget .set_text() → live native widgets
+ host main VM → View → Splash.view → live native widgets
```
-- **`crates/octoscript-render`** — backend-agnostic core: evaluates the Octoscript DSL in the makepad-script VM and walks it into a `UiNode` tree. Depends only on `makepad-script`. Unit-tested.
+- **`crates/octoscript-node`** — dependency-free `UiNode`/`Attrs` model shared by render backends.
+- **`crates/octoscript-render`** — backend-agnostic core: evaluates the OctoScript DSL in the makepad-script VM and walks it into a `UiNode` tree. Depends on `makepad-script`, the portable node model and `serde_json`; it has no platform/draw/widgets dependency. Unit-tested.
- **`crates/octoscript-makepad`** — the makepad backend: `to_makepad_ui(&UiNode) -> String` turns the tree into makepad's `View{}/Label{}/…` dialect. Pure, unit-tested — no makepad-platform/draw needed to build or test.
- **`crates/octoscript-widgets`** — the **themed native-widget kits** (Material 3 now; iOS / liquid-glass later), as **external `script_mod!` variants of makepad's widgets** (see *Fork-free theming* below).
- **`crates/makepad-d3`** — the **d3 grammar as native widgets** (scales, shapes, layouts, hierarchies, geo, 3D), registered into the VM under `mod.d3.*`. Grafted in with its history 2026-08-09 (was `mofa-org/makepad-d3`).
@@ -68,7 +74,7 @@ because the `Splash` isolate resolves `ui` against its own view root, the
## Fork-free theming (the key design point)
-makepad's native controls — checkbox, switch, radio, slider, text field — are drawn by their own MPSL shaders; their look is **not** reachable from the Octoscript DSL. It **is** reachable from an external crate, but only one way works:
+makepad's native controls — checkbox, switch, radio, slider, text field — are drawn by their own MPSL shaders; their look is **not** reachable from the OctoScript DSL. It **is** reachable from an external crate, but only one way works:
| Mechanism | Result |
|---|---|
@@ -79,13 +85,18 @@ The `script_mod!` macro compiles the MPSL at build time; a runtime string never
Each new theme is just more variants in `octoscript-widgets` + a `.octoscript` component library — no makepad fork per theme.
-### The one upstream PR
+### Current mount ownership
-Building + running the `kit-host` against upstream surfaced exactly **one** thing upstream doesn't have: a **`Splash` main-VM-mount option**. Upstream's `Splash` always allocates an *isolate* VM (`alloc_splash_vm_with_network(allow_net)`), but the light theme and a shared heap live on the app's **main** VM. The fix is the small `isolate: false` field this project's fork added to `widgets/src/splash.rs` — upstreaming it lets a trusted, app-generated kit mount on the main VM (correct theme, no isolate-heap animator panics). Until then the kit mounts on an isolate (dark-default theme). That is the *only* upstream change needed; everything else runs against upstream `dev` as-is.
+`kit-host::App::mount` and `beauty-host::App::mount_request` evaluate the generated
+widget source on the host's **main VM** using `cx.with_vm`, construct a `View`,
+and assign it to `Splash.view`. This keeps registered fonts and themed widgets
+in the same VM. They do not currently mount through `Splash::set_text`.
-These notes date from the `kit-host` bring-up. The workspace now builds against the
-`OctoSense-org/makepad` revision locked in `runtime.json` (`e29a0eaa`); that `Splash` has
-no `isolate` field, so the kit mounts on an isolate.
+Older bring-up notes described an isolate mount and a proposed `isolate: false`
+field. The pinned Makepad has no such field, but these hosts no longer depend
+on that proposal: the current main-VM mount is implemented in the hosts. See
+[the walkthrough](docs/architecture-walkthrough.md) before copying an older
+mount recipe. Other consumers can choose a different mount path.
## Shared runtime for OctoSense apps
@@ -109,7 +120,11 @@ resolved Cargo graph.
### Native application validation
-Build `cargo build --release -p kit-host --bin beauty-host` from this workspace.
+Prepare and verify the pinned siblings as described above. To open the catalog,
+run `cargo run -p kit-host --bin kit-host`. For a preview, build
+`cargo build --release -p kit-host --bin beauty-host` from this workspace.
+Set `BEAUTY_REQUEST` to a request JSON file containing card/data paths and
+viewport dimensions; see the [complete recipe](docs/architecture-walkthrough.md).
Launch the standalone host with `--remote`; automation sets
`MAKEPAD_HIDE_WINDOWS=1` and uses the built-in HTTP instrument on the native GPU
backend. Use `/snap`, input routes and `/g` to inspect the owned application;
@@ -123,16 +138,12 @@ extent, snapshot and lifecycle for application acceptance checks.
`cargo test --release -p octoscript-node -p octoscript-render -p octoscript-makepad`
checks the portable render pipeline and component contracts.
-## Status
-
-Status as of the `kit-host` bring-up; "upstream" below means upstream Makepad at that time. Today every crate here builds against the revisions in `runtime.json`.
+## Status and validation scope
-- ✅ `octoscript-render` + `octoscript-makepad` — portable render pipeline; **compile + test against upstream `makepad-script`** (rev `e1c2164b`), no fork
-- ✅ **Material 3 kit** — `components/material/catalog.octoscript`: ~35 components (buttons, FABs, cards, chips, nav bar/rail/drawer, app bars, dialog/menu/sheets as **real interactive overlays**, pickers, tabs, badges, toolbars), M3 tokens (colour, type scale + Medium weight, shape, elevation, surface tones), Font-Awesome monochrome icons, and real animation (circular spinner + shape-morph loading indicator)
-- ✅ `octoscript-widgets` — Material 3 native-control variants (checkbox/switch/radio/slider/text field) + `LoadingMorph`, fork-free; **compiles against upstream `makepad-widgets`**
-- ✅ **`apps/kit-host`** — generic app shell that **builds + runs against upstream makepad** (desktop, ~37 MB binary), fork-free, mounting the Material kit via `octoscript_widgets::widgets_mod`
-- ⏳ **The one upstream PR:** the `Splash` main-VM-mount option (see above) — the single change needed for correct light-theme rendering
-- ⏳ **Next:** that PR (or an isolate-VM theme/heap fix so the mount works isolated); Android build via `cargo-makepad`; Button **touch-ripple** as a `RippleButton` variant; **iOS** + **liquid-glass** kits
+The source includes checked evaluation, themed and measured-design translation,
+Material widgets, L0 native kits, chart widgets, and native catalog/preview
+hosts. Current pins are in [runtime.json](runtime.json). Device results above
+predate the current pins; rerun portable tests and native acceptance before shipping.
## License
diff --git a/README.zh-CN.md b/README.zh-CN.md
index bcf048e..d40ca91 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,24 +1,28 @@
-# Octoscript-Makepad
+# OctoScript-Makepad
[English](README.md) | 简体中文
> **要开发 OctoSense 应用?** 你不需要在这个仓库里工作。它是所有 OctoSense 外壳和 `card-host` 共同依赖的 UI 运行时;OctoScript-App-Design-Flow 的 `tools/setup-native.py` 会按固定版本把它检出为同级目录 `octoscript-makepad/`。请按 [OctoSense 组织主页](https://github.com/OctoSense-org)给出的顺序阅读:[OctoScript-App-Design-Flow `AGENTS.md`](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/AGENTS.md) → [`flows/README.md`](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/flows/README.md) → [`docs/QUICKSTART.md`](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/docs/QUICKSTART.md)。
-面向 **Octoscript DSL → makepad 原生控件**渲染器所构建应用的主题化、跨平台**组件套件**。
+面向 **OctoScript DSL → makepad 原生控件**渲染器所构建应用的主题化、跨平台**组件套件**。
-用纯数据形式的 Octoscript DSL 编写一次 UI:它在 makepad-script VM 中求值,被翻译成 makepad 自身的控件方言,并在运行时挂载为**真正的 makepad 原生控件**(支持设备上热重载)。本仓库既存放渲染管线,**也**存放基于这条管线的各套主题组件:目前是 Material 3,**iOS** 和 **liquid-glass** 在计划中。
+用纯数据形式的 OctoScript DSL 编写一次 UI:它在 makepad-script VM 中求值,被翻译成 makepad 自身的控件方言,并在运行时挂载为**真正的 makepad 原生控件**(支持设备上热重载)。本仓库既存放渲染管线,**也**存放基于这条管线的各套主题组件:目前是 Material 3,**iOS** 和 **liquid-glass** 在计划中。
+
+[源码导读与运行步骤](docs/architecture-walkthrough.md)先用一个文本标签说明源码如何变成原生控件,
+再介绍 L0 卡片、预览命令、状态与 agent 的边界。贡献约定见 [AGENTS.md](AGENTS.md)。
## 渲染管线
```
-Octoscript DSL ──► octoscript-render ──► UiNode tree ──► octoscript-makepad ──► makepad dialect string
+OctoScript DSL ──► octoscript-render ──► UiNode tree ──► octoscript-makepad ──► makepad dialect string
{t:"column", (makepad-script VM, (backend- (pure translation) View{…}/Label{…}/…
c:[ … ]} renderer-free) agnostic) │
▼
- makepad `Splash` widget .set_text() → live native widgets
+ host main VM → View → Splash.view → live native widgets
```
-- **`crates/octoscript-render`**:与后端无关的核心。在 makepad-script VM 中对 Octoscript DSL 求值,并遍历生成 `UiNode` 树。只依赖 `makepad-script`,有单元测试。
+- **`crates/octoscript-node`**:无依赖的 `UiNode`/`Attrs` 数据模型,供各渲染后端共享。
+- **`crates/octoscript-render`**:与后端无关的核心。在 makepad-script VM 中对 OctoScript DSL 求值,并遍历生成 `UiNode` 树。依赖 `makepad-script`、便携节点模型与 `serde_json`,不依赖 platform/draw/widgets;有单元测试。
- **`crates/octoscript-makepad`**:makepad 后端。`to_makepad_ui(&UiNode) -> String` 把这棵树转换成 makepad 的 `View{}/Label{}/…` 方言。纯函数,有单元测试,构建和测试都不需要 makepad-platform/draw。
- **`crates/octoscript-widgets`**:**主题化原生控件套件**(目前是 Material 3,之后是 iOS / liquid-glass),以**外部 `script_mod!` 变体的形式扩展 makepad 控件**(见下文*无需 fork 的主题化*)。
- **`crates/makepad-d3`**:**以原生控件实现的 d3 语法**(比例尺、形状、布局、层级、地理、3D),在 VM 中注册到 `mod.d3.*` 下。于 2026-08-09 连同提交历史一起并入(原为 `mofa-org/makepad-d3`)。
@@ -54,7 +58,7 @@ tools/visual-qa.sh # screenshot all 108 on the device
## 无需 fork 的主题化(关键设计点)
-makepad 的原生控件(复选框、开关、单选、滑块、文本框)由它们各自的 MPSL 着色器绘制;它们的外观**无法**从 Octoscript DSL 触及。外部 crate **可以**触及,但只有一种方式可行:
+makepad 的原生控件(复选框、开关、单选、滑块、文本框)由它们各自的 MPSL 着色器绘制;它们的外观**无法**从 OctoScript DSL 触及。外部 crate **可以**触及,但只有一种方式可行:
| 机制 | 结果 |
|---|---|
@@ -65,11 +69,15 @@ makepad 的原生控件(复选框、开关、单选、滑块、文本框)由
每个新主题只是在 `octoscript-widgets` 中多加一些变体,再加一个 `.octoscript` 组件库,不需要为每个主题 fork 一次 makepad。
-### 唯一一个上游 PR
+### 当前的挂载方式
-基于上游构建并运行 `kit-host` 时,只暴露出**一处**上游缺少的东西:**`Splash` 在主 VM 上挂载的选项**。上游的 `Splash` 总是分配一个 *isolate* VM(`alloc_splash_vm_with_network(allow_net)`),但浅色主题和共享堆都位于应用的**主** VM 上。修复方法是本项目的 fork 在 `widgets/src/splash.rs` 中新增的一个小字段 `isolate: false`;把它合入上游后,受信任的、由应用生成的套件就能挂载到主 VM 上(主题正确,也不会出现 isolate 堆上的 animator panic)。在此之前,套件挂载在 isolate 上(默认深色主题)。这是*唯一*需要的上游改动;其他一切都可以直接基于上游 `dev` 运行。
+`kit-host::App::mount` 与 `beauty-host::App::mount_request` 通过 `cx.with_vm`
+在宿主的**主 VM** 上求值生成的控件源码,构建 `View` 后赋给 `Splash.view`。
+字体与主题控件因此位于同一个 VM;这两个宿主当前不通过 `Splash::set_text` 挂载。
-以上记录来自 `kit-host` 初建时期。现在本工作区基于 `runtime.json` 锁定的 `OctoSense-org/makepad` 版本(`e29a0eaa`)构建;该版本的 `Splash` 没有 `isolate` 字段,所以套件挂载在 isolate 上。
+早期记录中的 isolate 挂载和拟议的 `isolate: false` 字段不是当前前提。
+锁定的 Makepad 没有该字段,但宿主已经自行实现主 VM 挂载。复制旧示例前请读
+[源码导读](docs/architecture-walkthrough.md);其他消费者仍需单独核对挂载路径。
## OctoSense 应用的共享运行时
@@ -81,22 +89,20 @@ makepad 的原生控件(复选框、开关、单选、滑块、文本框)由
### 原生应用验证
-在本工作区中运行 `cargo build --release -p kit-host --bin beauty-host` 进行构建。用 `--remote` 启动独立宿主;自动化流程会设置 `MAKEPAD_HIDE_WINDOWS=1`,并在原生 GPU 后端上使用内置的 HTTP 探测接口。用 `/snap`、输入路由和 `/g` 检查所控制的应用;最后调用 `/gq` 并确认进程已退出。Studio 不属于这个流程。
+先准备并验证上文的锁定依赖。运行组件目录使用
+`cargo run -p kit-host --bin kit-host`。预览宿主使用
+`cargo build --release -p kit-host --bin beauty-host` 构建,并设置 `BEAUTY_REQUEST`
+指向包含 card/data 文件路径和视口尺寸的 JSON;完整步骤见[源码导读](docs/architecture-walkthrough.md)。用 `--remote` 启动独立宿主;自动化流程会设置 `MAKEPAD_HIDE_WINDOWS=1`,并在原生 GPU 后端上使用内置的 HTTP 探测接口。用 `/snap`、输入路由和 `/g` 检查所控制的应用;最后调用 `/gq` 并确认进程已退出。Studio 不属于这个流程。
宿主接受经过测量的 AppCard 设计和 L0 卡片,在重新挂载时保留文本选区和滚动状态,并在导航时回收平台 WebView。在 macOS 上,它的自定义事件探针会暴露所控制 WebView 的内容、滚动范围、快照和生命周期,供应用验收检查使用。
`cargo test --release -p octoscript-node -p octoscript-render -p octoscript-makepad` 检查可移植的渲染管线和组件契约。
-## 状态
-
-以下状态记录于 `kit-host` 初建时期,其中的“上游”指当时的上游 Makepad。如今本仓库的所有 crate 都基于 `runtime.json` 中的版本构建。
+## 状态与验证范围
-- ✅ `octoscript-render` + `octoscript-makepad`:可移植渲染管线;**基于上游 `makepad-script` 编译并通过测试**(修订版本 `e1c2164b`),无 fork
-- ✅ **Material 3 套件**:`components/material/catalog.octoscript`,约 35 个组件(按钮、FAB、卡片、纸片、导航栏/导航轨/抽屉、应用栏,以**真正可交互的浮层**实现的对话框/菜单/面板,选择器、标签页、徽标、工具栏),M3 设计令牌(颜色、字号体系 + Medium 字重、形状、海拔、表面色调),Font-Awesome 单色图标,以及真正的动画(环形加载指示器 + 形状变形加载指示器)
-- ✅ `octoscript-widgets`:Material 3 原生控件变体(复选框/开关/单选/滑块/文本框)+ `LoadingMorph`,无需 fork;**基于上游 `makepad-widgets` 编译通过**
-- ✅ **`apps/kit-host`**:通用应用外壳,**基于上游 makepad 构建并运行**(桌面端,约 37 MB 二进制),无需 fork,通过 `octoscript_widgets::widgets_mod` 挂载 Material 套件
-- ⏳ **唯一一个上游 PR:** `Splash` 主 VM 挂载选项(见上文),这是正确渲染浅色主题所需的唯一改动
-- ⏳ **下一步:** 提交该 PR(或者修复 isolate VM 的主题/堆问题,让隔离挂载也能正常工作);通过 `cargo-makepad` 构建 Android;以 `RippleButton` 变体实现按钮**触摸涟漪**;**iOS** + **liquid-glass** 套件
+源码包含有执行预算的求值器、主题与设计稿翻译器、Material 控件、L0 原生套件、
+图表以及原生目录/预览宿主。当前依赖以 [runtime.json](runtime.json) 为准。
+上文设备结果早于当前锁定版本;发布前请重新运行便携测试和原生验收。
## 许可证
diff --git a/apps/kit-host/src/main.rs b/apps/kit-host/src/main.rs
index 2fd211f..43aeacb 100644
--- a/apps/kit-host/src/main.rs
+++ b/apps/kit-host/src/main.rs
@@ -73,12 +73,9 @@ script_mod! {
flow: Down
show_bg: true
draw_bg +: { color: #101417ff }
- // Upstream `Splash` always allocates an isolate VM. The
- // material kit needs the mount on the app's MAIN VM (light
- // theme + shared heap live there), which requires the one
- // upstream PR: a `Splash` main-VM-mount option (the
- // `isolate: false` field this fork added). Until then the
- // kit mounts on an isolate (dark-default theme).
+ // App::mount evaluates the widget source on the main VM
+ // and assigns the resulting View to this Splash container,
+ // keeping the registered fonts and theme on the same heap.
host := Splash{ width: Fill, height: Fit }
}
// Routing signal the mounted kit writes; the app reads it each frame.
diff --git a/docs/architecture-walkthrough.md b/docs/architecture-walkthrough.md
new file mode 100644
index 0000000..32a6a47
--- /dev/null
+++ b/docs/architecture-walkthrough.md
@@ -0,0 +1,234 @@
+# Code walkthrough: from app source to native widgets
+
+OctoSense is a shell that hosts apps. Octos runs their agents. This repository
+turns UI descriptions into native Makepad widgets. Follow a small text label
+through that process first, then use the later sections for L0 cards, previews
+and application state.
+
+## What this repository runs
+
+A native Rust application is compiled into a binary with Makepad widgets and
+Rust event handlers. An OctoScript app supplies source and data to such a host;
+the host evaluates it and mounts native widgets. Both use Makepad's UI event
+loop. Agents, network access and storage come from the host's adapters and grants.
+
+A **DSL** is a language designed for a particular task; here it describes a UI.
+The plain-data DSL represents each element as an object with a tag (`t`),
+attributes such as `text`, and optional children (`c`). A **VM**, or virtual
+machine, evaluates that source. The renderer converts its result into ordinary
+Rust data before a backend creates widget source.
+
+
+
+## Follow one label from source to screen
+
+This illustrative Rust fragment uses the public renderer APIs. It was checked
+against the source and an existing test, but has not been executed here. It
+needs no host capabilities:
+
+```rust
+let source = r#"{t:"text", text:"Hello", h:28}"#;
+let tree = octoscript_render::build(source, |_| {}).expect("valid UI source");
+assert_eq!(tree.kind, octoscript_node::NodeKind::Text);
+assert_eq!(tree.attrs.text.as_deref(), Some("Hello"));
+let widget_source = octoscript_makepad::to_makepad_ui(&tree);
+```
+
+1. **Evaluate the source.** In [eval.rs](../crates/octoscript-render/src/eval.rs),
+ `build` creates a fresh `ScriptVm` and evaluates the object. Its `walk_inner`
+ function reads `t` as the node kind, `text` as an attribute, and `h` as height.
+ The result is a `UiNode` with kind `Text`, text `Hello`, height `28` and no
+ children. The [node model](../crates/octoscript-node/src/node.rs) is portable
+ Rust data with no renderer dependency.
+2. **Translate the tree.** In [lib.rs](../crates/octoscript-makepad/src/lib.rs),
+ `to_makepad_ui` clones the tree, expands marks for AI-authored text, resolves
+ text contrast, then emits widget source. `widget_name` maps `Text` to `Label`;
+ `emit_attrs` writes the text property. The `Label` portion is shown below;
+ surrounding layout and generated font properties are omitted:
+
+ ```text
+ Label {
+ text: "Hello"
+ }
+ ```
+
+3. **Mount the widgets.** The string still needs a native host. In the
+ [catalog host](../apps/kit-host/src/main.rs), `App::mount` evaluates generated
+ widget source on the app's **main VM** through `cx.with_vm`, then assigns the
+ resulting `View` to `Splash.view`. Splash is the container that displays it.
+ The earlier evaluation built a data tree; this evaluation creates the live UI.
+4. **Handle the next action.** `handle_actions` and `handle_event` receive UI
+ actions, update Rust-held state and remount the UI when needed. The host
+ supplies the current values again because each `build` uses a fresh VM.
+ Rendering once does not subscribe the label to a database.
+
+For a larger version of this path, read `column_of_text_becomes_view_with_label`
+in the [translator tests](../crates/octoscript-makepad/src/lib.rs). It checks
+that a styled column emits a `RoundedView` containing a `Label` and the
+expected text.
+
+## Where L0 cards and measured designs enter
+
+An **L0 card** is a checked UI description that can refer to app data and
+instance state. **Realization** checks those references against the supplied
+values and produces a complete card tree. **Lowering** converts that tree into
+the more detailed UI source needed by a rendering backend. A **kit** supplies
+the component definitions and styling used during that conversion.
+
+| Input | Entry point | Output |
+| --- | --- | --- |
+| Plain-data UI DSL, as in the label above | `octoscript_render::build` | Portable `UiNode` tree |
+| L0 card, data and optional instance state | `octoscript_makepad::l0::prepare_with_state` | Realized and lowered source plus `UiNode` |
+| Design source with explicit positions and sizes | `octoscript_makepad::design::prepare` | Checked `UiNode`, preserving that geometry |
+| `UiNode` | `to_makepad_ui`, `to_makepad_l0_ui`, or `design::to_makepad_ui` | Makepad widget source for a host to mount |
+
+In [l0.rs](../crates/octoscript-makepad/src/l0.rs), `prepare_with_state` calls
+`realize_with_state`, then `complete_root` refuses incomplete output. Preparation
+then takes one of two paths:
+
+- Native kit components load `native//kit.json`. `kit_pack::lower` produces
+ design source, and `design::prepare` builds its tree.
+- Other components load the palette, theme choices such as radius and density
+ (the code calls these **theme axes**), helpers that derive style values, and
+ `_kit.octoscript`. The assembled source is then evaluated into a tree.
+
+`PreparedCard.native_components` tells the host which translator to use.
+`realize_with_state`, `InstanceStore` and `kit_pack` belong to the external
+`octoscript-ui-l0` crate in the
+[OctoScript repository](https://github.com/OctoSense-org/Octoscript/tree/main/crates/octoscript-ui-l0).
+This workspace's [runtime lock](../runtime.json) selects that crate's revision.
+
+The [design translator](../crates/octoscript-makepad/src/design.rs) preserves
+explicit geometry. It also checks **semantic kit bindings**: mappings from a
+component's role, such as an input field, to the actual child widget that fills
+that role. For example, `kit_contract` requires an `input` binding to name a
+native `TextInput`. This lets a styled component retain real input behavior.
+
+The regular and L0 translators both expand AI text marks before resolving
+contrast and emitting source; expanding the marks again does not duplicate
+them. The measured-design translator has its own emission path. For L0 events,
+`to_makepad_l0_ui_with_events` embeds a host-selected event channel. The host
+handles the events, updates data and state, and decides when to render again.
+
+## Runtime limits and native host details
+
+The two evaluation stages have separate limits:
+
+| Stage | Behavior |
+| --- | --- |
+| Source → `UiNode` through `build` | `eval_checked` allows 2,000,000 instructions. Tree walking allows depth 128 and 65,536 nodes. Evaluation errors, unknown tags, malformed children or exhausted limits fail the whole build with `None`. |
+| Widget source → live UI in catalog `kit-host` | Uses `eval_with_append_source` on the main VM, without an explicit instruction budget. |
+| Widget source → live UI in preview `beauty-host` | Uses `eval_checked(sm, 2_000_000)` on the main VM. |
+
+The [preview host](../apps/kit-host/src/beauty.rs) adds inspection and replacement
+handling around the normal rendering steps. `mount_request` reads the
+`BEAUTY_REQUEST` JSON file, prepares a design or L0 card, assigns inspectable IDs,
+and replaces `Splash.view`. It retains the old view through replacement drawing,
+retires overlays and WebViews, and restores focus, selection and scroll state.
+
+[Native themes](../crates/octoscript-widgets/src/lib.rs) register compiled widgets
+and shaders through `script_mod!` modules.
+[makepad-d3](../crates/makepad-d3/README.md) and
+[makepad-plot](../crates/makepad-plot/README.md) add chart widgets under `mod.d3.*`
+and `mod.plot.*`. The node crate also supplies
+[AI text marks](../crates/octoscript-node/src/ai.rs),
+[numeric widget state](../crates/octoscript-node/src/state.rs) and
+[unit conversions](../crates/octoscript-node/src/units.rs).
+
+Keep the source set consistent when building a host.
+[runtime.json](../runtime.json) selects Makepad and OctoScript revisions;
+[Cargo.toml](../Cargo.toml) declares the crates and sibling overrides. Two
+Makepad copies can create incompatible Rust types and separate VM heaps.
+Check a consuming app's runtime lock before changing its framework checkout.
+
+## Run the framework examples
+
+The commands below are source-checked recipes. Their build, GUI and device
+execution is **unverified** in this documentation pass.
+
+Run from this repository after installing Rust, Cargo and Makepad's native
+build prerequisites. First prepare and check the dependencies; preparation uses
+Git and network access.
+
+```sh
+python3 tools/runtime.py prepare
+python3 tools/runtime.py verify --cargo-manifest Cargo.toml
+cargo test --release -p octoscript-node -p octoscript-render -p octoscript-makepad
+```
+
+To inspect generated widget source without opening a window, run the
+[translate example](../crates/octoscript-makepad/examples/translate.rs). It uses
+a built-in sample; append `-- /absolute/path/example.octoscript` to read your
+own source instead.
+
+```sh
+cargo run -p octoscript-makepad --example translate
+```
+
+Choose a native viewer below. Each command runs until you close that viewer:
+
+```sh
+cargo run -p kit-host --bin kit-host
+SPLASH_ROUTE=l0/weather cargo run -p kit-host --bin kit-host
+cargo run -p flutter-samples
+```
+
+`kit-host` has two binaries; name `--bin kit-host` explicitly. In
+[kit-host](../apps/kit-host/src/main.rs), `current_route` reads the device route
+file, then `SPLASH_ROUTE`, then defaults to `button`. Its `current_source(&self)`
+first accepts a device-pushed source file, then tries the in-app screen and
+finally that route. The [Flutter host](../apps/flutter-samples/src/lib.rs) has
+a separate `current_source()` selecting device-pushed source or its baked
+catalog. See the [Flutter catalog limitations](../components/flutter/README.md)
+for the scope of that port.
+
+For a measured design or L0 acceptance run:
+
+```sh
+cargo build --release -p kit-host --bin beauty-host
+BEAUTY_REQUEST=/absolute/path/request.json target/release/beauty-host --remote
+```
+
+`request.json` must supply `card` (source-file path), `data` (JSON-file path),
+`width` and `height`. L0 input also needs `kit_dir`; measured design input uses
+`"format": "design"`. Optional `layout` and `actions` paths collect measurements
+and actions. Even a design request currently reads the data file, so provide
+an existing JSON file (for example `{}`). Paths are read by the host process;
+use absolute paths for reproducibility. Obtain card and kit inputs from the
+[design flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow).
+The native HTTP instrument is enabled by `--remote`; follow its emitted
+connection information for `/snap`, `/g`, input routes and `/gq`.
+`MAKEPAD_HIDE_WINDOWS=1` hides windows during automated native GPU checks.
+
+Android requires Makepad's Android toolchain and a device or emulator; the sample
+command is `cargo makepad android run -p flutter-samples --release`.
+OctoSense builds its desktop, Home and ROM packages in the OctoSense repository.
+
+## State, app data and agents are different things
+
+`octoscript_node::state` is a small widget-state helper, not the application's
+persistent database. L0 `InstanceStore` supplies per-instance UI state. The
+host owns app records, network services and agent integration, and passes
+approved values and capabilities into evaluation. For production app stores and
+peer routing, continue with the
+[OctoSense walkthrough](https://github.com/OctoSense-org/OctoSense/blob/61c668279a7c38a0f8056134d8d29e42ed715806/docs/architecture-walkthrough.md).
+
+Schedule blocking network requests and model inference outside the Makepad UI
+thread, then send completions back to update state and redraw. The consuming
+host owns that scheduling and the cost of its synchronous evaluation callbacks.
+
+## Verification and debugging
+
+Portable tests exercise tree validity, evaluation budgets, lowering and emitted
+widget contracts. They cannot prove font metrics, keyboard focus, WebView
+lifecycle or touch behavior. For those, use the native preview and inspect its
+measured layout, actions and screenshots. Common starting points:
+
+- `build` returns `None`: inspect the source, registered capabilities, unknown
+ tags and instruction/tree limits before changing the widget translator.
+- A themed control is blank: check registration of compiled widgets and the VM
+ on which the final view was evaluated.
+- A card shows old values: follow host event handling, state update and remount;
+ evaluating a source once does not subscribe it to a database.
+- Cargo reports duplicate Makepad crates: repair the pinned sibling source set
+ and verify the resolved graph before editing type definitions.