From 2b11be54fa01e5b4e2209501a8274038531b3ca1 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Fri, 2 Oct 2026 00:09:34 -0700 Subject: [PATCH 1/5] docs: explain app admission, hosting and agent service boundaries --- AGENTS.md | 39 +++++ README.md | 20 ++- README.zh-CN.md | 17 ++- docs/CODE-WALKTHROUGH.md | 305 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 376 insertions(+), 5 deletions(-) create mode 100644 AGENTS.md create mode 100644 docs/CODE-WALKTHROUGH.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..348b001 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,39 @@ +# Working on App Hub + +Read [README.md](README.md), the junior Rust +[code walkthrough](docs/CODE-WALKTHROUGH.md), and the relevant crate before +editing. This repository owns the app contract, admission, catalog/signing, +store, contained runner and shared host-service transport. OctoSense owns +the shells, first-party services and live agent integration; Design Flow +owns authoring workflows. + +- Trace behavior to executable code. Distinguish manifest validation, + resolved grants, shell registration and an actual executor. `AgentBundle` + loading alone does not start a peer or install instructions/skills. +- Keep native `AppModule`, Splash script bundles and Octoscript L0 cards + distinct. `tools/octo` is Design Flow's Python CLI; octos is the agent + kernel. `card-host` supplies no registered host services or agent runtime. +- For agent/storage changes, also inspect OctoSense `crates/shell/src/host_tools`, + `crates/shell/src/app_storage`, `crates/ai-host` and `crates/app-peers` at + the consumer's actual pin. Do not claim store script tools run merely + because `tools.json` passes the gate. +- Preserve contract compatibility and refusal behavior. Consult + [app-contract's compatibility rules](crates/app-contract/README.md). + Do not widen an app's resolved grants in a mounting path. +- Use the prepared sibling source layout from `Cargo.toml`; do not replace + pins or regenerate locks as a side effect of a documentation edit. +- Match validation to the change: contract/policy/hub tests for admission, + `card-host` CLI tests for arguments, relevant service tests for lifecycle + changes. Documentation-only changes need source/link/command checks; + report unavailable builds or devices explicitly. +- Keep English and Chinese README summaries aligned. Preserve historical + evidence and label source-reviewed commands separately from commands run. +- Use hidden windows for automated GUI checks, a distinct bridge port and + app-data directory per instance, and quit only instances you started. +- Do not change real `catalog.json`, `index/`, `artifacts/`, publisher keys + or publication status as part of ordinary documentation/development work. + Use a temporary local fixture for install tests; publishing follows + [PUBLISHING.md](docs/PUBLISHING.md) and the user's authorized scope. + +`AGENTS.md` instructs repository contributors. A bundle's singular +`AGENT.md` is runtime app-agent material with separate contract rules. diff --git a/README.md b/README.md index 2baee1d..b022cca 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,15 @@ English | [简体中文](README.zh-CN.md) The index of apps published for OctoSense, the signed catalog every OctoSense store reads, the hub's own copy of each admitted bundle, and the code that -runs the hub and the store. No app code lives here; each app stays in its -publisher's repository. +runs the hub and the store. Publisher app source stays in each publisher's repository; this repository +also contains the store UI, runtime hosts, templates and test fixtures. | Looking for | Repository | | --- | --- | | How to build an app: quickstart, script API, script-app template, design flows, examples | [OctoScript-App-Design-Flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow) | -| The AppCard assistant runtime (opt-in in the shells, `--features app-appcard`) and the L0 card language | [OctoSense `apps/appcard`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/appcard) | +| The AppCard assistant runtime (opt-in in the shells, `--features app-appcard`) | [OctoSense `apps/appcard`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/appcard) | | The first-party system apps (News, Photos, Maps, Camera, Mail, AI providers) and their host services (`mail`, `llm`) | [OctoSense `apps/`](https://github.com/OctoSense-org/OctoSense/tree/main/apps) | +| The L0 parser/checker and its Makepad lowering/renderer | [Octoscript](https://github.com/OctoSense-org/Octoscript) and [Octoscript-Makepad](https://github.com/OctoSense-org/Octoscript-Makepad) | | The bundle format, the gate, signing, submission and the store | this repository | **Building an app?** Start at the [OctoSense-org profile](https://github.com/OctoSense-org)'s "read these first" list (OctoScript-App-Design-Flow's `AGENTS.md`, then its `docs/QUICKSTART.md`). You need this repository only as a sibling checkout to build `hub` and `card-host`, and to submit (an issue here, see [Submitting](docs/PUBLISHING.md#submitting)). Clone it; do not edit `catalog.json`, `index/` or `artifacts/`. @@ -44,6 +45,19 @@ resolved from sibling checkouts (`../makepad`, `../octoscript-makepad`, runs the policy, gate, signing and store tests headless; `cargo run -p octosense-app-hub --bin hub` is the publishing tool. +## Code walkthrough for Rust beginners + +Read [docs/CODE-WALKTHROUGH.md](docs/CODE-WALKTHROUGH.md) for the package-to-UI +call chain, native `AppModule` versus Splash/L0 apps, exact development +commands, storage and host-service reply routing, and the boundary between +agent declarations and working shell peers/tools. Contributor instructions +are in [AGENTS.md](AGENTS.md). + +`card-host` applies containment but registers no host services and starts no +octos kernel. To test app-agent conversations, use the full OctoSense shell. +The shell owns peer identities, conversation contexts and Tokio scheduling; +App Hub provides policy and the UI request/reply transport. + ## Trust anchor Stores trust this anchor and follow its certificate to the working key that diff --git a/README.zh-CN.md b/README.zh-CN.md index 2be3314..4632e81 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -2,13 +2,14 @@ [English](README.md) | 简体中文 -这里是为 OctoSense 发布的应用索引、每个 OctoSense 商店都会读取的签名目录、App Hub 为每个已准入应用包保存的副本,以及运行 hub 和商店的代码。这里不存放任何应用代码,每个应用都留在其发布者自己的仓库中。 +这里是为 OctoSense 发布的应用索引、每个 OctoSense 商店都会读取的签名目录、App Hub 为每个已准入应用包保存的副本,以及运行 hub 和商店的代码。发布者的应用源码留在各自仓库中;本仓库也包含商店 UI、运行宿主、模板和测试夹具。 | 想找 | 仓库 | | --- | --- | | 如何开发应用:快速上手、脚本 API、脚本应用模板、设计流程、示例 | [OctoScript-App-Design-Flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow) | -| AppCard 助手运行时(在 Shell 中需 `--features app-appcard` 才启用)与 L0 卡片语言 | [OctoSense `apps/appcard`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/appcard) | +| AppCard 助手运行时(在 Shell 中需 `--features app-appcard` 才启用) | [OctoSense `apps/appcard`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/appcard) | | 第一方系统应用(新闻、相册、地图、相机、邮件、AI providers)及其宿主服务(`mail`、`llm`) | [OctoSense `apps/`](https://github.com/OctoSense-org/OctoSense/tree/main/apps) | +| L0 解析器/检查器及其 Makepad 转换/渲染层 | [Octoscript](https://github.com/OctoSense-org/Octoscript) 与 [Octoscript-Makepad](https://github.com/OctoSense-org/Octoscript-Makepad) | | 应用包格式、准入检查、签名、提交与商店 | 本仓库 | **要开发应用?** 请从 [OctoSense-org 主页](https://github.com/OctoSense-org)的“请按顺序先阅读”列表开始(先读 OctoScript-App-Design-Flow 的 `AGENTS.md`,再读其 `docs/QUICKSTART.md`)。你只需要把本仓库作为兄弟目录克隆下来,用于构建 `hub` 和 `card-host`,以及提交应用(在这里开 issue,见[提交](docs/PUBLISHING.md#submitting))。不要修改 `catalog.json`、`index/` 或 `artifacts/`。 @@ -37,6 +38,18 @@ 这些 crate 基于固定版本的 OctoSense Makepad 与 Octoscript 分支构建,和启动器工作区一样,从同级检出目录(`../makepad`、`../octoscript-makepad`、`../octoscript`)解析依赖。`cargo test --workspace` 以无界面方式运行策略、准入检查、签名和商店测试;`cargo run -p octosense-app-hub --bin hub` 是发布工具。 +## 面向 Rust 初学者的代码导读 + +[代码导读(英文)](docs/CODE-WALKTHROUGH.md) 从包验证、商店安装追踪到 UI 挂载, +区分原生 `AppModule`、Splash 脚本和 Octoscript L0 卡片,并说明运行命令、存储、 +宿主服务回包,以及 Agent 声明与 Shell 中真实可运行的 Peer/工具之间的边界。 +仓库协作规则见 [AGENTS.md](AGENTS.md)。 + +`card-host` 执行隔离策略,但不注册宿主服务,也不启动 octos 内核。 +应用 Agent 对话需在完整 OctoSense Shell 中验证。Peer 身份、会话上下文和 Tokio +调度由 Shell/内核负责;App Hub 提供策略与 UI 请求/应答传输。 +发布者应用源码位于各自仓库;本仓库也包含商店 UI、运行宿主、模板和测试夹具。 + ## 信任锚 商店信任这个锚,并沿着它的证书找到为目录签名的工作密钥。轮换工作密钥不需要发布新版商店。 diff --git a/docs/CODE-WALKTHROUGH.md b/docs/CODE-WALKTHROUGH.md new file mode 100644 index 0000000..c7a3846 --- /dev/null +++ b/docs/CODE-WALKTHROUGH.md @@ -0,0 +1,305 @@ +# App Hub code walkthrough for Rust beginners + +This walkthrough follows App Hub `41bc959` and the sibling OctoSense source +on 2026-10-01. It explains the code, not a claim that every command below +has been run on every platform. Build, GUI and device commands below are +**unverified in this documentation review**. Follow the source links when +your checkout has a different revision. + +## 1. What runs where + +An **app** provides a user interface and data. An **agent** is a model-driven +conversation that can request tools; a tool is a named operation with JSON +arguments and a host implementation. A **peer** is the octos kernel's +identity and routing boundary for an agent. None of these words means an +operating-system process, Rust thread, or Tokio task. + +App Hub supplies package admission, distribution and hosting. OctoSense +supplies the desktop/phone shells, app-agent peers and the octos runtime. +Installing a bundle or parsing an `agent` declaration here does not start a +model. The Python `tools/octo` in Design Flow is a development command; +**octos** is the separate Rust agent kernel. + +| App form | What executes | Where to start | +| --- | --- | --- | +| Native Rust app | A compiled `AppModule` creates widgets and a `ServiceExecutor` | [`app-host/src/lib.rs`](../crates/app-host/src/lib.rs); native modules live in OctoSense | +| Contained script app | `main.splash` is evaluated by Makepad's Script VM inside a Splash widget | [`entry.rs`](../crates/app-contract/src/entry.rs), [`card-host/src/host.rs`](../crates/card-host/src/host.rs) | +| L0 card app | `page.card` plus data and a kit is parsed/realized/lowered to Makepad UI | `card_source` and `lower` in [`host.rs`](../crates/card-host/src/host.rs) | + +The project name OctoScript does not make `.splash` and `.card` the same +language. Splash is the Makepad Script containment/UI path. L0 uses the +Octoscript parser and `octoscript-makepad` lowering, then reaches Makepad. +A native Rust module can also embed Splash UI; its Rust implementation is +still compiled into its host. + +```mermaid +flowchart LR + Author[Design Flow tools/octo] --> Gate[hub: stamp/check/scan] + Gate --> Catalog[Signed catalog and bundles] + Catalog --> Store[Store: verify and install] + Store --> Runner[Shell CardModule] + Bundle[Local development bundle] --> Standalone[card-host] + Runner --> Splash[Policy-configured Splash isolate] + Standalone --> Splash + Splash --> Pump[Host request pump] + Pump --> Services[Services registered by OctoSense] + Services --> Agents[Shell app peers and octos] +``` + +The last two boxes are supplied by the shell. Standalone `card-host` has a +pump but registers no host services. + +## 2. Read the crates in this order + +1. [`app-contract/src/lib.rs`](../crates/app-contract/src/lib.rs): the + shared, versioned data contract. `AppManifest` describes requests; + `AppPolicy` describes grants. This crate parses an agent block but does + not create or authorize an octos session. +2. [`app-policy/src/policy.rs`](../crates/app-policy/src/policy.rs): resolve + the app contract plus agent requests against `HostLimits`. +3. [`app-policy/src/agent.rs`](../crates/app-policy/src/agent.rs): validate + `tools.json`, instructions and skills; construct an `AgentBundle`. +4. [`app-hub/src/gate.rs`](../crates/app-hub/src/gate.rs): produce the same + admission report for local development and publication. +5. [`app-hub/src/client.rs`](../crates/app-hub/src/client.rs): the device's + `Store`, catalog verification, installation and permission to run. +6. [`appstore/src/cardapp.rs`](../crates/appstore/src/cardapp.rs): mount a + verified app in its own shell client. +7. [`appstore/src/services.rs`](../crates/appstore/src/services.rs): route + script host requests and deliver replies. + +For a junior Rust reader: `Result` means success containing `T` +or an explanatory refusal; `?` propagates a refusal. `Option` represents +absence, such as no agent. Traits such as `HostService` and `AppModule` +describe interfaces; `Box` stores implementations behind +one interface. `Mutex` protects shared data, but does not create a worker. + +## 3. From a manifest to a contained UI + +Follow `policy_for` → `App::mount` in +[`card-host/src/host.rs`](../crates/card-host/src/host.rs): + +1. Read `manifest.json`, compute the bundle digest, and optionally stamp + the development copy. `admit_and_resolve_dir` checks the bytes and policy. +2. Use default limits for a store app or `HostLimits::system()` for a + system app. The defaults in + [`app-contract/src/policy.rs`](../crates/app-contract/src/policy.rs) + include 16 MiB storage, 64 MiB heap and 20 million script instructions; + system defaults include 64 MiB storage, 128 MiB heap and 4 billion + instructions. Requests above ceilings are clamped. +3. `isolate_settings` in + [`containers.rs`](../crates/app-policy/src/containers.rs) chooses + `/` as the jail. An `AssetServer` serves bundle + artwork on a loopback port; only its own port is added to the allowlist. +4. [`splash_adapter::apply`](../crates/app-policy/src/splash_adapter.rs) + sets jail, quota, capabilities, prompt permission, host allowlist, + instruction budget, heap limit and network access **before** evaluation. +5. `card_source` loads `main.splash`, or realizes `page.card` with + `page.data.json` and `kit/`. Card lowering first tries measured design; + ordinary L0 kit cards fall back to kit lowering. The output enters + `Splash::set_text` and the Makepad event/draw loop. + +A log saying `agent read-only` reports resolved metadata. This mount path +does not construct an agent runtime. Likewise `AppPolicy::session_profile` +is a serializable helper, not the shell's complete peer/storage setup. + +## 4. From publication to launch + +[`hub.rs`](../crates/app-hub/src/bin/hub.rs) dispatches the CLI commands; +[`hub-usage.txt`](../crates/app-hub/src/bin/hub-usage.txt) is their syntax. +`stamp` records a digest. `check` calls `check_bundle`: manifest admission, +bundle constraints, listing, references, secret-field checks and agent-file +review. A passing gate does not prove UI behavior or screenshot quality. +`scan` prepares a review packet and optionally invokes a reviewer command +([`scan.rs`](../crates/app-hub/src/scan.rs)); it is not the device's app agent. + +`publish` rechecks admission, copies the reviewed bundle and writes a signed +catalog. [`signing.rs`](../crates/app-hub/src/signing.rs) implements the +anchor/working-key trust chain. [`pack.rs`](../crates/app-hub/src/pack.rs) +encodes a bundle for transport. The catalog is distributed as files; a +separate central always-running octos service is not required by this code. + +On the device, `Origin` in +[`appstore/src/source.rs`](../crates/appstore/src/source.rs) fetches a local +directory or HTTP origin. `Store::accept_catalog` verifies the signature +and rejects a sequence older than the catalog it already holds. Installation +checks freshness and bundle bytes before writing +`//bundle`. The 14-day freshness window pauses new installs; +it does not by itself stop already-installed apps. + +`CardAppView::start` reopens the last verified catalog and calls +`Store::may_run` for installed apps. A withdrawn version is refused on a +subsequent open using that catalog; this is not a live process-kill service. +System apps instead come from +[`system::prepare`](../crates/appstore/src/system.rs), which unpacks a +compiled-in pack and applies system limits. + +The shell-facing crate is +[`app-hub-app`](../crates/app-hub-app/README.md). Its +[`build.rs`](../crates/app-hub-app/build.rs) reads `OCTOSENSE_SYSTEM_APPS` +to pack the selected first-party bundles. Without that selection it ships +no system apps. `APP_HUB_MODULE` is the newer native store UI; +`CARD_MODULE` wraps the common Card runner. The standalone `appstore` +binary uses `APPSTORE_MODULE` from `appstore` through `AppHostView`; +the store preview and standalone store are not full shells. + +## 5. A host-service request, line by line + +Consider a granted app calling +`host.request("mail.list", args, callback)`: + +1. Makepad's Splash host API checks the capability and queues a request + identified by `(heap_key, req_id)`. A heap identifies an isolate; it is + not a peer slug. +2. The runner calls `services::pump` on UI events. It avoids executing + callbacks during drawing. It collects requests for this app and its + visible host sheet only, parses arguments and builds `ServiceCall` with + app identity, `from_sheet`, `may_prompt` and the host directory. +3. `dispatch` finds a registered `HostService` by the `mail` family. + Missing service returns `no service answers "mail" on this device`. + Requests to `mail.sheet.*` from an app are refused before dispatch. +4. The Rust service may finish now or move its `Replier` to a worker. + `Replier::send` removes the pending request, queues a JSON reply and + wakes the UI using `SignalToUI`. +5. A later `pump` delivers the result to the original isolate callback. + A late or duplicate reply is ignored; closing an isolate calls + `cancel_heap`, so it cannot answer a replacement app instance. + +The default timeout is 60 seconds, with 32 pending requests per isolate and +256 globally. Arguments are bounded at 1 MiB and replies at 4 MiB. Services +may override the timeout. A host sheet suspends its request's deadline +while waiting for the person. The sheet owns its isolate and password input; +the app receives the service's result, not its credential. + +These queues use `Mutex` and a native `std::thread` timeout sweeper. App Hub +does not map each service call or widget to a Tokio task. The octos side has +its own async scheduling, explained in the +[OctoSense walkthrough](https://github.com/OctoSense-org/OctoSense/blob/main/docs/architecture-walkthrough.md). + +## 6. What declaring an app agent actually enables + +`AgentBundle::load` checks the digest again and validates the declaration. +`tools.json` describes tool names, schemas, risk, sharing, confirmation and +implementation ownership. A contained app's namespace is its id's last +segment; a native module uses its module id. `shareable: true` means a tool +can be granted to another caller, not that every agent gets it automatically. + +`agent.tools` asks for tools from outside this manifest. Only +`ask_user_question` is an allowed plain kernel-tool name in contained app +policy. Dotted names must also be offered by the host. The default list is +in `HostLimits`; arbitrary `mail.send`, peer or shell privileges are not +granted just because the file names them. Host-level relay support is not +evidence that a default store manifest can pass admission with those names. + +| Layer | Present in this source | What still requires shell support | +| --- | --- | --- | +| `agent`, model needs, background and triggers | Parsed and validated; budgets resolved | Selection by model needs and trigger/background scheduling are not implemented by these declarations | +| `AGENT.md` and `skills/` | Reviewed and loaded into `AgentBundle` | Current shell loader does not install their contents into app peers | +| `tools.json` | Names, schemas and policy checked | An executable handler; store app script tools have no dispatcher yet | +| Agent account data | Contract has `storage.accounts` and `agent_workspace` | Shell constructs the account workspace and its bounded read tools | +| Human/app conversation | No chat runtime in `card-host` | Shell consent, app peer and chat surfaces | + +For the implementation boundary, read OctoSense's +[`script_apps.rs`](https://github.com/OctoSense-org/OctoSense/blob/main/crates/shell/src/host_tools/script_apps.rs). +It installs tool declarations and a `HostServiceExecutor`. Tools marked +`implemented_by: "host-service"` can reach a registered service when the +family is granted (or is a system app's own family). Script-implemented +tools return `app_tool_unavailable`; opening the app does not currently +supply the missing script dispatcher. The generic `CardExecutor` here also +returns unavailable. Existing system apps supply Rust service handlers; +a store bundle cannot add one simply by shipping JSON. + +In the shell, the person can use the desktop **Ask <app>** panel, +an app's own `octos.*` UI, or supported L0 card chat. The phone's general +per-app panel entry is not implemented at this snapshot. The system agent +discovers permitted prepared peers and delegates using their actual peer +slug. A system request and a human request can reach the same app peer with +separate conversation lanes; the reply is routed back to its requester. +They do not automatically get a shared transcript. + +The app agent's data workspace is normally its account folder, +`accounts/device/` for a single-account app. The shell exposes bounded read +tools; the agent is not handed an unrestricted database or every file in +the app's jail. App-owned records must be in the exposed workspace or +accessible through an implemented tool. A Rust host service's `.host` +state and secrets stay outside it. See +[`app_storage`](https://github.com/OctoSense-org/OctoSense/tree/main/crates/shell/src/app_storage) +and [`app-peers/storage.rs`](https://github.com/OctoSense-org/OctoSense/blob/main/crates/app-peers/src/storage.rs). + +Cross-app tools require the owner's declaration, `shareable`, the caller's +grant and an executable owner route, plus approval where required. App +agents are not unrestricted system agents: do not assume they can invoke +`peer_send_input` or ask the system agent to bypass their permissions. + +## 7. Run the right host + +First prepare sibling sources using Design Flow's +[native workspace instructions](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/docs/NATIVE-WORKSPACE.md). +This workspace's [`Cargo.toml`](../Cargo.toml) patches paths to `../makepad`, +`../octoscript-makepad` and `../octoscript`. Missing siblings can prevent even +Cargo metadata or a policy-only test from resolving. A consumer's top-level +patches determine its actual versions; do not mix arbitrary latest engines +with a different consumer's runtime lock. + +From App Hub (commands source-checked, not built/run in this review): + +```sh +cargo build --release -p octosense-card-host -p octosense-app-hub +cargo run -p octosense-app-hub --bin hub -- help +cargo test -p octosense-app-contract -p octosense-app-policy -p octosense-app-hub +cargo test -p octosense-card-host --test cli +``` + +Run a disposable unsigned development bundle: + +```sh +MAKEPAD_HIDE_WINDOWS=1 MAKEPAD_REMOTE=8141 cargo run --release \ + -p octosense-card-host -- --bundle /absolute/path/my-app/bundle \ + --app-data /absolute/path/my-app/.local-state --allow-unsigned --stamp +``` + +That command stays in the foreground. In another terminal: + +```sh +curl -s http://127.0.0.1:8141/snap +curl -s http://127.0.0.1:8141/quit +``` + +`--stamp` writes the manifest; use a development copy. This host uses +`RefuseAllSignatures`, so `--allow-unsigned` does not make a signed manifest +verifiable. Use the store path to test signatures. `--system` changes +admission limits for first-party bundles; it does not register Mail, models +or octos. Run shell integration to test those services. + +For a native module, the standalone app binary registers `AppHostView` and +calls `open_in(module, open_json)`. In [`app-host`](../crates/app-host/src/lib.rs), +`create` validates arguments, allocates a Splash VM, supplies scoped +storage/viewport/reply handles and calls the Rust module. Event and draw +calls enter its VM. Its `ServiceExecutor` is retained but never called by +an assistant; upstream bus messages are drained. Running the same module +inside OctoSense adds the broker and agent integration. + +To exercise distribution without publishing, use the documented +[fixture/preview commands](../crates/app-hub-app/README.md#exercise-installation-without-publishing-apps). +The fixture generates a local catalog and isolated environment settings; +only the full shell opens installed apps as clients. Native app, desktop, +Home APK and ROM build commands belong to the +[OctoSense README](https://github.com/OctoSense-org/OctoSense/blob/main/README.md). + +## 8. Debug by boundary + +| Symptom | First source/check | +| --- | --- | +| Cargo cannot find a manifest under a sibling path | Workspace patches and prepared runtime pins | +| Bundle refused | `hub check`; `gate.rs`, contract/policy resolution and digest | +| App admitted, blank UI | `card-host` log, `/snap`, script parse/lowering and asset paths | +| `no service answers` | `register_host_service` in the shell, not more bundle capabilities | +| Agent tool appears but fails | Owner/grant/executor route in shell `host_tools`; JSON is not implementation | +| Agent cannot see app records | Active account workspace and file placement, then storage read-tool limits | +| App peer absent | Shell consent and peer preparation; `card-host` has no peer list | + +Verification in this review: `git diff --check`, changed-file relative-link +checks and `cargo metadata --no-deps --offline --format-version 1` passed. +Metadata without dependency resolution does not verify a build. +No provider-backed conversation, GUI launch, signed install or device run +is claimed by this walkthrough. From f560e9b1e751d9ab7d4ba7f74204ee37056d27dd Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Fri, 2 Oct 2026 00:55:30 -0700 Subject: [PATCH 2/5] docs: address architecture review and clarify runtime boundaries --- AGENTS.md | 2 +- README.md | 14 ++-- README.zh-CN.md | 11 +--- docs/CODE-WALKTHROUGH.md | 136 ++++++++++++++++++++++----------------- 4 files changed, 87 insertions(+), 76 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 348b001..97cbfcf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # Working on App Hub -Read [README.md](README.md), the junior Rust +Read [README.md](README.md), the [code walkthrough](docs/CODE-WALKTHROUGH.md), and the relevant crate before editing. This repository owns the app contract, admission, catalog/signing, store, contained runner and shared host-service transport. OctoSense owns diff --git a/README.md b/README.md index b022cca..12afe3e 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,16 @@ English | [简体中文](README.zh-CN.md) The index of apps published for OctoSense, the signed catalog every OctoSense store reads, the hub's own copy of each admitted bundle, and the code that -runs the hub and the store. Publisher app source stays in each publisher's repository; this repository -also contains the store UI, runtime hosts, templates and test fixtures. +runs the hub and the store. Publisher app source stays in each publisher's +repository; this repository also contains the store UI, runtime hosts, +templates and test fixtures. | Looking for | Repository | | --- | --- | | How to build an app: quickstart, script API, script-app template, design flows, examples | [OctoScript-App-Design-Flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow) | | The AppCard assistant runtime (opt-in in the shells, `--features app-appcard`) | [OctoSense `apps/appcard`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/appcard) | | The first-party system apps (News, Photos, Maps, Camera, Mail, AI providers) and their host services (`mail`, `llm`) | [OctoSense `apps/`](https://github.com/OctoSense-org/OctoSense/tree/main/apps) | -| The L0 parser/checker and its Makepad lowering/renderer | [Octoscript](https://github.com/OctoSense-org/Octoscript) and [Octoscript-Makepad](https://github.com/OctoSense-org/Octoscript-Makepad) | +| The L0 parser/checker and its Makepad lowering/renderer | [Octoscript](https://github.com/OctoSense-org/Octoscript) and [Octoscript-Makepad](https://github.com/OctoSense-org/OctoScript-Makepad) | | The bundle format, the gate, signing, submission and the store | this repository | **Building an app?** Start at the [OctoSense-org profile](https://github.com/OctoSense-org)'s "read these first" list (OctoScript-App-Design-Flow's `AGENTS.md`, then its `docs/QUICKSTART.md`). You need this repository only as a sibling checkout to build `hub` and `card-host`, and to submit (an issue here, see [Submitting](docs/PUBLISHING.md#submitting)). Clone it; do not edit `catalog.json`, `index/` or `artifacts/`. @@ -45,7 +46,7 @@ resolved from sibling checkouts (`../makepad`, `../octoscript-makepad`, runs the policy, gate, signing and store tests headless; `cargo run -p octosense-app-hub --bin hub` is the publishing tool. -## Code walkthrough for Rust beginners +## Code walkthrough Read [docs/CODE-WALKTHROUGH.md](docs/CODE-WALKTHROUGH.md) for the package-to-UI call chain, native `AppModule` versus Splash/L0 apps, exact development @@ -53,11 +54,6 @@ commands, storage and host-service reply routing, and the boundary between agent declarations and working shell peers/tools. Contributor instructions are in [AGENTS.md](AGENTS.md). -`card-host` applies containment but registers no host services and starts no -octos kernel. To test app-agent conversations, use the full OctoSense shell. -The shell owns peer identities, conversation contexts and Tokio scheduling; -App Hub provides policy and the UI request/reply transport. - ## Trust anchor Stores trust this anchor and follow its certificate to the working key that diff --git a/README.zh-CN.md b/README.zh-CN.md index 4632e81..ff9fa87 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -9,7 +9,7 @@ | 如何开发应用:快速上手、脚本 API、脚本应用模板、设计流程、示例 | [OctoScript-App-Design-Flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow) | | AppCard 助手运行时(在 Shell 中需 `--features app-appcard` 才启用) | [OctoSense `apps/appcard`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/appcard) | | 第一方系统应用(新闻、相册、地图、相机、邮件、AI providers)及其宿主服务(`mail`、`llm`) | [OctoSense `apps/`](https://github.com/OctoSense-org/OctoSense/tree/main/apps) | -| L0 解析器/检查器及其 Makepad 转换/渲染层 | [Octoscript](https://github.com/OctoSense-org/Octoscript) 与 [Octoscript-Makepad](https://github.com/OctoSense-org/Octoscript-Makepad) | +| L0 解析器/检查器及其 Makepad 转换/渲染层 | [Octoscript](https://github.com/OctoSense-org/Octoscript) 与 [Octoscript-Makepad](https://github.com/OctoSense-org/OctoScript-Makepad) | | 应用包格式、准入检查、签名、提交与商店 | 本仓库 | **要开发应用?** 请从 [OctoSense-org 主页](https://github.com/OctoSense-org)的“请按顺序先阅读”列表开始(先读 OctoScript-App-Design-Flow 的 `AGENTS.md`,再读其 `docs/QUICKSTART.md`)。你只需要把本仓库作为兄弟目录克隆下来,用于构建 `hub` 和 `card-host`,以及提交应用(在这里开 issue,见[提交](docs/PUBLISHING.md#submitting))。不要修改 `catalog.json`、`index/` 或 `artifacts/`。 @@ -38,18 +38,13 @@ 这些 crate 基于固定版本的 OctoSense Makepad 与 Octoscript 分支构建,和启动器工作区一样,从同级检出目录(`../makepad`、`../octoscript-makepad`、`../octoscript`)解析依赖。`cargo test --workspace` 以无界面方式运行策略、准入检查、签名和商店测试;`cargo run -p octosense-app-hub --bin hub` 是发布工具。 -## 面向 Rust 初学者的代码导读 +## 代码导读 [代码导读(英文)](docs/CODE-WALKTHROUGH.md) 从包验证、商店安装追踪到 UI 挂载, 区分原生 `AppModule`、Splash 脚本和 Octoscript L0 卡片,并说明运行命令、存储、 -宿主服务回包,以及 Agent 声明与 Shell 中真实可运行的 Peer/工具之间的边界。 +宿主服务应答,以及应用 Agent 的声明与 Shell 中实际可执行的 Peer 和工具之间的边界。 仓库协作规则见 [AGENTS.md](AGENTS.md)。 -`card-host` 执行隔离策略,但不注册宿主服务,也不启动 octos 内核。 -应用 Agent 对话需在完整 OctoSense Shell 中验证。Peer 身份、会话上下文和 Tokio -调度由 Shell/内核负责;App Hub 提供策略与 UI 请求/应答传输。 -发布者应用源码位于各自仓库;本仓库也包含商店 UI、运行宿主、模板和测试夹具。 - ## 信任锚 商店信任这个锚,并沿着它的证书找到为目录签名的工作密钥。轮换工作密钥不需要发布新版商店。 diff --git a/docs/CODE-WALKTHROUGH.md b/docs/CODE-WALKTHROUGH.md index c7a3846..197ae28 100644 --- a/docs/CODE-WALKTHROUGH.md +++ b/docs/CODE-WALKTHROUGH.md @@ -1,23 +1,24 @@ -# App Hub code walkthrough for Rust beginners +# App Hub code walkthrough -This walkthrough follows App Hub `41bc959` and the sibling OctoSense source -on 2026-10-01. It explains the code, not a claim that every command below -has been run on every platform. Build, GUI and device commands below are -**unverified in this documentation review**. Follow the source links when -your checkout has a different revision. +App Hub takes an app from a manifest and bundle to a verified installation +and a contained UI. This walkthrough follows that path, then shows where +OctoSense adds app agents and host services. Use this workspace's +[`Cargo.toml`](../Cargo.toml) and [`Cargo.lock`](../Cargo.lock), and the +[consumer's Cargo manifest](https://github.com/OctoSense-org/OctoSense/blob/main/Cargo.toml), +to identify the source versions used by your build. ## 1. What runs where An **app** provides a user interface and data. An **agent** is a model-driven conversation that can request tools; a tool is a named operation with JSON arguments and a host implementation. A **peer** is the octos kernel's -identity and routing boundary for an agent. None of these words means an -operating-system process, Rust thread, or Tokio task. +identity and routing boundary for an agent. These are logical roles; §5 +covers the threads and queues that carry their work. App Hub supplies package admission, distribution and hosting. OctoSense supplies the desktop/phone shells, app-agent peers and the octos runtime. -Installing a bundle or parsing an `agent` declaration here does not start a -model. The Python `tools/octo` in Design Flow is a development command; +The shell starts model work after preparing an allowed app peer. The Python +`tools/octo` in Design Flow is a development command; **octos** is the separate Rust agent kernel. | App form | What executes | Where to start | @@ -26,8 +27,7 @@ model. The Python `tools/octo` in Design Flow is a development command; | Contained script app | `main.splash` is evaluated by Makepad's Script VM inside a Splash widget | [`entry.rs`](../crates/app-contract/src/entry.rs), [`card-host/src/host.rs`](../crates/card-host/src/host.rs) | | L0 card app | `page.card` plus data and a kit is parsed/realized/lowered to Makepad UI | `card_source` and `lower` in [`host.rs`](../crates/card-host/src/host.rs) | -The project name OctoScript does not make `.splash` and `.card` the same -language. Splash is the Makepad Script containment/UI path. L0 uses the +Splash is the Makepad Script containment/UI path. L0 uses the Octoscript parser and `octoscript-makepad` lowering, then reaches Makepad. A native Rust module can also embed Splash UI; its Rust implementation is still compiled into its host. @@ -53,8 +53,8 @@ pump but registers no host services. 1. [`app-contract/src/lib.rs`](../crates/app-contract/src/lib.rs): the shared, versioned data contract. `AppManifest` describes requests; - `AppPolicy` describes grants. This crate parses an agent block but does - not create or authorize an octos session. + `AppPolicy` describes grants. The shell uses these declarations when + preparing an authorized octos session. 2. [`app-policy/src/policy.rs`](../crates/app-policy/src/policy.rs): resolve the app contract plus agent requests against `HostLimits`. 3. [`app-policy/src/agent.rs`](../crates/app-policy/src/agent.rs): validate @@ -68,11 +68,24 @@ pump but registers no host services. 7. [`appstore/src/services.rs`](../crates/appstore/src/services.rs): route script host requests and deliver replies. -For a junior Rust reader: `Result` means success containing `T` -or an explanatory refusal; `?` propagates a refusal. `Option` represents -absence, such as no agent. Traits such as `HostService` and `AppModule` -describe interfaces; `Box` stores implementations behind -one interface. `Mutex` protects shared data, but does not create a worker. +The remaining crates and supporting directories complete the delivery path: + +| Path | Role and next file | +| --- | --- | +| [`card-host`](../crates/card-host/src/main.rs) | Standalone contained bundle runner; argument parsing leads to `host::run` | +| [`app-host`](../crates/app-host/src/lib.rs) | One-window host for a compiled Rust `AppModule` | +| [`app-hub-app`](../crates/app-hub-app/README.md) | Shell integration: native store, Card runner, packed system apps and icons | +| [`appstore-app`](../crates/appstore-app/src/lib.rs) | Standalone `appstore` executable using `AppHostView` | +| [`card-studio`](../crates/card-studio/src/main.rs) | Hidden `card-host` captures at glance, phone and desktop sizes; measured checks and critique payload | +| [`skills/card-studio`](../skills/card-studio/SKILL.md) | octos skill exposing card rendering and critique preparation | +| [`templates/app`](../templates/app/README.md) | Card-app scaffold with bundle metadata and contributor instructions | + +OctoSense consumes a git revision of App Hub selected by its `Cargo.toml`. +OctoSense, App Hub and Rinx request `octosense-app-contract = "1"` from +crates.io; the consumer lock records the resolved release. This workspace +alone patches that dependency to `crates/app-contract` for development. +Cargo applies patches from the top-level workspace, so that local patch +is not inherited by a shell consuming App Hub as a dependency. ## 3. From a manifest to a contained UI @@ -99,9 +112,9 @@ Follow `policy_for` → `App::mount` in ordinary L0 kit cards fall back to kit lowering. The output enters `Splash::set_text` and the Makepad event/draw loop. -A log saying `agent read-only` reports resolved metadata. This mount path -does not construct an agent runtime. Likewise `AppPolicy::session_profile` -is a serializable helper, not the shell's complete peer/storage setup. +A log saying `agent read-only` reports resolved metadata. +`AppPolicy::session_profile` serializes that policy; the shell builds the +actual peer and account storage. ## 4. From publication to launch @@ -109,27 +122,29 @@ is a serializable helper, not the shell's complete peer/storage setup. [`hub-usage.txt`](../crates/app-hub/src/bin/hub-usage.txt) is their syntax. `stamp` records a digest. `check` calls `check_bundle`: manifest admission, bundle constraints, listing, references, secret-field checks and agent-file -review. A passing gate does not prove UI behavior or screenshot quality. -`scan` prepares a review packet and optionally invokes a reviewer command -([`scan.rs`](../crates/app-hub/src/scan.rs)); it is not the device's app agent. +review. UI behavior and screenshot quality are checked by running the app +and reviewing captures. `scan` prepares a review packet and optionally +invokes a publishing reviewer command +([`scan.rs`](../crates/app-hub/src/scan.rs)). `publish` rechecks admission, copies the reviewed bundle and writes a signed catalog. [`signing.rs`](../crates/app-hub/src/signing.rs) implements the anchor/working-key trust chain. [`pack.rs`](../crates/app-hub/src/pack.rs) -encodes a bundle for transport. The catalog is distributed as files; a -separate central always-running octos service is not required by this code. +encodes a bundle for transport. The catalog and artifacts are static files, +served by an HTTP origin or read from a local directory. On the device, `Origin` in [`appstore/src/source.rs`](../crates/appstore/src/source.rs) fetches a local directory or HTTP origin. `Store::accept_catalog` verifies the signature and rejects a sequence older than the catalog it already holds. Installation checks freshness and bundle bytes before writing -`//bundle`. The 14-day freshness window pauses new installs; -it does not by itself stop already-installed apps. +`//bundle`. The 14-day freshness window applies to new installs. +Already-installed apps remain subject to `may_run`. `CardAppView::start` reopens the last verified catalog and calls `Store::may_run` for installed apps. A withdrawn version is refused on a -subsequent open using that catalog; this is not a live process-kill service. +subsequent open using that catalog. An already-running instance keeps its +current lifecycle until the host closes it. System apps instead come from [`system::prepare`](../crates/appstore/src/system.rs), which unpacks a compiled-in pack and applies system limits. @@ -141,7 +156,7 @@ to pack the selected first-party bundles. Without that selection it ships no system apps. `APP_HUB_MODULE` is the newer native store UI; `CARD_MODULE` wraps the common Card runner. The standalone `appstore` binary uses `APPSTORE_MODULE` from `appstore` through `AppHostView`; -the store preview and standalone store are not full shells. +launching installed app clients is the full shell's responsibility. ## 5. A host-service request, line by line @@ -149,8 +164,8 @@ Consider a granted app calling `host.request("mail.list", args, callback)`: 1. Makepad's Splash host API checks the capability and queues a request - identified by `(heap_key, req_id)`. A heap identifies an isolate; it is - not a peer slug. + identified by `(heap_key, req_id)`. The heap key selects the originating + isolate, and the request id selects its callback. 2. The runner calls `services::pump` on UI events. It avoids executing callbacks during drawing. It collects requests for this app and its visible host sheet only, parses arguments and builds `ServiceCall` with @@ -171,10 +186,9 @@ may override the timeout. A host sheet suspends its request's deadline while waiting for the person. The sheet owns its isolate and password input; the app receives the service's result, not its credential. -These queues use `Mutex` and a native `std::thread` timeout sweeper. App Hub -does not map each service call or widget to a Tokio task. The octos side has -its own async scheduling, explained in the -[OctoSense walkthrough](https://github.com/OctoSense-org/OctoSense/blob/main/docs/architecture-walkthrough.md). +These queues use `Mutex` and a native `std::thread` timeout sweeper. The +octos side uses async scheduling, explained in the +[OctoSense walkthrough](https://github.com/OctoSense-org/OctoSense/blob/docs/junior-architecture-walkthrough/docs/architecture-walkthrough.md). ## 6. What declaring an app agent actually enables @@ -182,14 +196,13 @@ its own async scheduling, explained in the `tools.json` describes tool names, schemas, risk, sharing, confirmation and implementation ownership. A contained app's namespace is its id's last segment; a native module uses its module id. `shareable: true` means a tool -can be granted to another caller, not that every agent gets it automatically. +can be granted to another caller; the caller still needs that grant. `agent.tools` asks for tools from outside this manifest. Only `ask_user_question` is an allowed plain kernel-tool name in contained app policy. Dotted names must also be offered by the host. The default list is -in `HostLimits`; arbitrary `mail.send`, peer or shell privileges are not -granted just because the file names them. Host-level relay support is not -evidence that a default store manifest can pass admission with those names. +in `HostLimits`; default admission rejects names outside that list, +including `mail.send`. | Layer | Present in this source | What still requires shell support | | --- | --- | --- | @@ -209,27 +222,40 @@ supply the missing script dispatcher. The generic `CardExecutor` here also returns unavailable. Existing system apps supply Rust service handlers; a store bundle cannot add one simply by shipping JSON. -In the shell, the person can use the desktop **Ask <app>** panel, -an app's own `octos.*` UI, or supported L0 card chat. The phone's general -per-app panel entry is not implemented at this snapshot. The system agent +The system bundles demonstrate this split: News has read and notification +tools; Mail has `mail.notify`; Calendar has event and card tools. Photos, +Maps, Camera and YouTube declare their own `.notify`, executed +by the shell's shared +[`glance_notice` service](https://github.com/OctoSense-org/OctoSense/blob/main/crates/shell/src/glance_notice.rs). +These declarations add an agent and a notice route, not general access to +camera controls or photo records. AI providers remains excluded from that +set: its `ai-providers` namespace fails the tool-name rule. The shell's +[`script_apps` tests](https://github.com/OctoSense-org/OctoSense/blob/main/crates/shell/src/host_tools/script_apps.rs) +record these exact tool rosters. + +The shell supplies the desktop `Ask ` panel, app-owned `octos.*` UI +and supported L0 card chat. See the +[shell chat surfaces](https://github.com/OctoSense-org/OctoSense/blob/docs/junior-architecture-walkthrough/docs/architecture-walkthrough.md#6-where-a-person-talks-and-where-the-answer-goes) +for their entry points. The system agent discovers permitted prepared peers and delegates using their actual peer slug. A system request and a human request can reach the same app peer with separate conversation lanes; the reply is routed back to its requester. -They do not automatically get a shared transcript. +Each lane owns its transcript; sharing contexts receive bounded recent +history from the other lane, and the shell panel can display both. The app agent's data workspace is normally its account folder, -`accounts/device/` for a single-account app. The shell exposes bounded read -tools; the agent is not handed an unrestricted database or every file in -the app's jail. App-owned records must be in the exposed workspace or +`accounts/device/` for a single-account app. On Unix, the shell exposes bounded +`files.list/read/search` tools when the person has consented and that workspace +is available. App-owned records must be in the exposed workspace or accessible through an implemented tool. A Rust host service's `.host` state and secrets stay outside it. See [`app_storage`](https://github.com/OctoSense-org/OctoSense/tree/main/crates/shell/src/app_storage) and [`app-peers/storage.rs`](https://github.com/OctoSense-org/OctoSense/blob/main/crates/app-peers/src/storage.rs). Cross-app tools require the owner's declaration, `shareable`, the caller's -grant and an executable owner route, plus approval where required. App -agents are not unrestricted system agents: do not assume they can invoke -`peer_send_input` or ask the system agent to bypass their permissions. +grant and an executable owner route, plus approval where required. +Contained app agents cannot call `peer_send_input` or acquire system-agent +privileges through this tool route. ## 7. Run the right host @@ -241,7 +267,7 @@ Cargo metadata or a policy-only test from resolving. A consumer's top-level patches determine its actual versions; do not mix arbitrary latest engines with a different consumer's runtime lock. -From App Hub (commands source-checked, not built/run in this review): +From App Hub. **Validation status: build, GUI and device execution unverified.** ```sh cargo build --release -p octosense-card-host -p octosense-app-hub @@ -297,9 +323,3 @@ Home APK and ROM build commands belong to the | Agent tool appears but fails | Owner/grant/executor route in shell `host_tools`; JSON is not implementation | | Agent cannot see app records | Active account workspace and file placement, then storage read-tool limits | | App peer absent | Shell consent and peer preparation; `card-host` has no peer list | - -Verification in this review: `git diff --check`, changed-file relative-link -checks and `cargo metadata --no-deps --offline --format-version 1` passed. -Metadata without dependency resolution does not verify a build. -No provider-backed conversation, GUI launch, signed install or device run -is claimed by this walkthrough. From 20aec66b1a3362200dd9e134f5a198d6bd83fcb5 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Fri, 2 Oct 2026 00:59:41 -0700 Subject: [PATCH 3/5] docs: keep companion walkthrough links stable after merge --- docs/CODE-WALKTHROUGH.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CODE-WALKTHROUGH.md b/docs/CODE-WALKTHROUGH.md index 197ae28..ce89ff6 100644 --- a/docs/CODE-WALKTHROUGH.md +++ b/docs/CODE-WALKTHROUGH.md @@ -188,7 +188,7 @@ the app receives the service's result, not its credential. These queues use `Mutex` and a native `std::thread` timeout sweeper. The octos side uses async scheduling, explained in the -[OctoSense walkthrough](https://github.com/OctoSense-org/OctoSense/blob/docs/junior-architecture-walkthrough/docs/architecture-walkthrough.md). +[OctoSense walkthrough](https://github.com/OctoSense-org/OctoSense/blob/c3011a2057ec59738b79466f48ff2ad8d0e60130/docs/architecture-walkthrough.md). ## 6. What declaring an app agent actually enables @@ -235,7 +235,7 @@ record these exact tool rosters. The shell supplies the desktop `Ask ` panel, app-owned `octos.*` UI and supported L0 card chat. See the -[shell chat surfaces](https://github.com/OctoSense-org/OctoSense/blob/docs/junior-architecture-walkthrough/docs/architecture-walkthrough.md#6-where-a-person-talks-and-where-the-answer-goes) +[shell chat surfaces](https://github.com/OctoSense-org/OctoSense/blob/c3011a2057ec59738b79466f48ff2ad8d0e60130/docs/architecture-walkthrough.md#6-where-a-person-talks-and-where-the-answer-goes) for their entry points. The system agent discovers permitted prepared peers and delegates using their actual peer slug. A system request and a human request can reach the same app peer with From 19bb52d402e80e89e085dea989615e3ec612d359 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Fri, 2 Oct 2026 09:36:37 -0700 Subject: [PATCH 4/5] docs: clarify walkthroughs for junior Rust readers --- AGENTS.md | 3 + README.md | 11 +- README.zh-CN.md | 8 +- docs/CODE-WALKTHROUGH.md | 212 ++++++++++++++++++++++++--------------- 4 files changed, 144 insertions(+), 90 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 97cbfcf..e04a542 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,9 @@ owns authoring workflows. `card-host` CLI tests for arguments, relevant service tests for lifecycle changes. Documentation-only changes need source/link/command checks; report unavailable builds or devices explicitly. +- In walkthroughs, lead with a launch path, then trace one request to its + reply. Define routing terms at first use and keep source inventories after + the main path. Preserve prerequisites and capability limits in examples. - Keep English and Chinese README summaries aligned. Preserve historical evidence and label source-reviewed commands separately from commands run. - Use hidden windows for automated GUI checks, a distinct bridge port and diff --git a/README.md b/README.md index 12afe3e..5b26263 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,12 @@ octosense-app-hub --bin hub` is the publishing tool. ## Code walkthrough -Read [docs/CODE-WALKTHROUGH.md](docs/CODE-WALKTHROUGH.md) for the package-to-UI -call chain, native `AppModule` versus Splash/L0 apps, exact development -commands, storage and host-service reply routing, and the boundary between -agent declarations and working shell peers/tools. Contributor instructions -are in [AGENTS.md](AGENTS.md). +Start with [the walkthrough's host and launch choices](docs/CODE-WALKTHROUGH.md#2-run-the-right-host), +then trace a bundle into its UI and a host-service reply back to its callback. +A saved-notes request connects app-agent conversations, account storage and +tool grants. The walkthrough distinguishes native `AppModule`, Splash and +L0 apps, with the crate inventory at the end. Contributor instructions are +in [AGENTS.md](AGENTS.md). ## Trust anchor diff --git a/README.zh-CN.md b/README.zh-CN.md index ff9fa87..d1f2d5f 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -40,10 +40,10 @@ ## 代码导读 -[代码导读(英文)](docs/CODE-WALKTHROUGH.md) 从包验证、商店安装追踪到 UI 挂载, -区分原生 `AppModule`、Splash 脚本和 Octoscript L0 卡片,并说明运行命令、存储、 -宿主服务应答,以及应用 Agent 的声明与 Shell 中实际可执行的 Peer 和工具之间的边界。 -仓库协作规则见 [AGENTS.md](AGENTS.md)。 +先看[代码导读中的宿主选择与启动命令(英文)](docs/CODE-WALKTHROUGH.md#2-run-the-right-host), +再追踪应用包如何进入 UI,以及宿主服务的应答如何回到回调函数。“总结已保存的笔记” +这一请求串起应用 Agent 的对话、账户存储与工具授权。导读区分原生 `AppModule`、 +Splash 脚本和 L0 卡片,并把 crate 索引放在最后。仓库协作规则见 [AGENTS.md](AGENTS.md)。 ## 信任锚 diff --git a/docs/CODE-WALKTHROUGH.md b/docs/CODE-WALKTHROUGH.md index ce89ff6..b3a17af 100644 --- a/docs/CODE-WALKTHROUGH.md +++ b/docs/CODE-WALKTHROUGH.md @@ -7,6 +7,12 @@ OctoSense adds app agents and host services. Use this workspace's [consumer's Cargo manifest](https://github.com/OctoSense-org/OctoSense/blob/main/Cargo.toml), to identify the source versions used by your build. +For a first run, identify your app form below, then use +[§2](#2-run-the-right-host). Follow its bundle through admission, mounting +and a service reply in §§3–5. [§6](#6-what-declaring-an-app-agent-actually-enables) +adds a conversation to that app; the crate inventory is in +[§7](#7-source-reference). + ## 1. What runs where An **app** provides a user interface and data. An **agent** is a model-driven @@ -32,6 +38,9 @@ Octoscript parser and `octoscript-makepad` lowering, then reaches Makepad. A native Rust module can also embed Splash UI; its Rust implementation is still compiled into its host. +An **isolate** is the app's separate script execution environment. Its storage +**jail** is the directory tree available to its sandboxed file operations. + ```mermaid flowchart LR Author[Design Flow tools/octo] --> Gate[hub: stamp/check/scan] @@ -49,43 +58,62 @@ flowchart LR The last two boxes are supplied by the shell. Standalone `card-host` has a pump but registers no host services. -## 2. Read the crates in this order + -1. [`app-contract/src/lib.rs`](../crates/app-contract/src/lib.rs): the - shared, versioned data contract. `AppManifest` describes requests; - `AppPolicy` describes grants. The shell uses these declarations when - preparing an authorized octos session. -2. [`app-policy/src/policy.rs`](../crates/app-policy/src/policy.rs): resolve - the app contract plus agent requests against `HostLimits`. -3. [`app-policy/src/agent.rs`](../crates/app-policy/src/agent.rs): validate - `tools.json`, instructions and skills; construct an `AgentBundle`. -4. [`app-hub/src/gate.rs`](../crates/app-hub/src/gate.rs): produce the same - admission report for local development and publication. -5. [`app-hub/src/client.rs`](../crates/app-hub/src/client.rs): the device's - `Store`, catalog verification, installation and permission to run. -6. [`appstore/src/cardapp.rs`](../crates/appstore/src/cardapp.rs): mount a - verified app in its own shell client. -7. [`appstore/src/services.rs`](../crates/appstore/src/services.rs): route - script host requests and deliver replies. +## 2. Run the right host -The remaining crates and supporting directories complete the delivery path: +First prepare sibling sources using Design Flow's +[native workspace instructions](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/docs/NATIVE-WORKSPACE.md). +This workspace's [`Cargo.toml`](../Cargo.toml) patches paths to `../makepad`, +`../octoscript-makepad` and `../octoscript`. Missing siblings can prevent even +Cargo metadata or a policy-only test from resolving. A consumer's top-level +patches determine its actual versions; do not mix arbitrary latest engines +with a different consumer's runtime lock. -| Path | Role and next file | -| --- | --- | -| [`card-host`](../crates/card-host/src/main.rs) | Standalone contained bundle runner; argument parsing leads to `host::run` | -| [`app-host`](../crates/app-host/src/lib.rs) | One-window host for a compiled Rust `AppModule` | -| [`app-hub-app`](../crates/app-hub-app/README.md) | Shell integration: native store, Card runner, packed system apps and icons | -| [`appstore-app`](../crates/appstore-app/src/lib.rs) | Standalone `appstore` executable using `AppHostView` | -| [`card-studio`](../crates/card-studio/src/main.rs) | Hidden `card-host` captures at glance, phone and desktop sizes; measured checks and critique payload | -| [`skills/card-studio`](../skills/card-studio/SKILL.md) | octos skill exposing card rendering and critique preparation | -| [`templates/app`](../templates/app/README.md) | Card-app scaffold with bundle metadata and contributor instructions | +From App Hub. **Validation status: build, GUI and device execution unverified.** -OctoSense consumes a git revision of App Hub selected by its `Cargo.toml`. -OctoSense, App Hub and Rinx request `octosense-app-contract = "1"` from -crates.io; the consumer lock records the resolved release. This workspace -alone patches that dependency to `crates/app-contract` for development. -Cargo applies patches from the top-level workspace, so that local patch -is not inherited by a shell consuming App Hub as a dependency. +```sh +cargo build --release -p octosense-card-host -p octosense-app-hub +cargo run -p octosense-app-hub --bin hub -- help +cargo test -p octosense-app-contract -p octosense-app-policy -p octosense-app-hub +cargo test -p octosense-card-host --test cli +``` + +Run a disposable unsigned development bundle: + +```sh +MAKEPAD_HIDE_WINDOWS=1 MAKEPAD_REMOTE=8141 cargo run --release \ + -p octosense-card-host -- --bundle /absolute/path/my-app/bundle \ + --app-data /absolute/path/my-app/.local-state --allow-unsigned --stamp +``` + +That command stays in the foreground. In another terminal: + +```sh +curl -s http://127.0.0.1:8141/snap +curl -s http://127.0.0.1:8141/quit +``` + +`--stamp` writes the manifest; use a development copy. This host uses +`RefuseAllSignatures`, so `--allow-unsigned` does not make a signed manifest +verifiable. Use the store path to test signatures. `--system` changes +admission limits for first-party bundles; it does not register Mail, models +or octos. Run shell integration to test those services. + +For a native module, the standalone app binary registers `AppHostView` and +calls `open_in(module, open_json)`. In [`app-host`](../crates/app-host/src/lib.rs), +`create` validates arguments, allocates a Splash VM, supplies scoped +storage/viewport/reply handles and calls the Rust module. Event and draw +calls enter its VM. Its `ServiceExecutor` is retained but never called by +an assistant; upstream bus messages are drained. Running the same module +inside OctoSense adds the broker and agent integration. + +To exercise distribution without publishing, use the documented +[fixture/preview commands](../crates/app-hub-app/README.md#exercise-installation-without-publishing-apps). +The fixture generates a local catalog and isolated environment settings; +only the full shell opens installed apps as clients. Native app, desktop, +Home APK and ROM build commands belong to the +[OctoSense README](https://github.com/OctoSense-org/OctoSense/blob/main/README.md). ## 3. From a manifest to a contained UI @@ -192,6 +220,37 @@ octos side uses async scheduling, explained in the ## 6. What declaring an app agent actually enables +### Follow a request for saved notes + +The `mail.list` call in §5 is a UI-to-service request: it needs no model. +Now consider a different request, “Summarize my saved notes,” sent to an +app agent. Assume the app has stored those notes in its account workspace +and the person has allowed its agent in the OctoSense shell. + +1. A person opens desktop `Ask ` and sends the request. The shell + selects that app's peer—the agent identity—and its human conversation. + An app-owned chat can instead enter through `octos.turn.start`, using + the host-request transport from §5 to reach the shell's agent service. +2. The model can request the shell's bounded `files.list/read/search` + tools on Unix. These read the exposed account folder; merely declaring + `tools.json` does not make every UI record readable. +3. Tool results return to the model, which produces an answer for the + originating human conversation. If the system assistant delegated the + same question, it uses the app peer's separate system conversation and + gathers that conversation's result instead. +4. A follow-up requiring another app's operation must pass that tool's + admission, sharing and execution checks. For example, adding + `mail.send` to `agent.tools` fails default admission; it is not a working + cross-app recipe. + +This example ties together three separate decisions: admission grants what +the app may request, the shell supplies tools that can actually execute, +and the active conversation determines where the answer returns. +Standalone `card-host` stops before this agent path because it has no +registered services or agent runtime. + +### Declarations and executable tools + `AgentBundle::load` checks the digest again and validates the declaration. `tools.json` describes tool names, schemas, risk, sharing, confirmation and implementation ownership. A contained app's namespace is its id's last @@ -233,6 +292,8 @@ set: its `ai-providers` namespace fails the tool-name rule. The shell's [`script_apps` tests](https://github.com/OctoSense-org/OctoSense/blob/main/crates/shell/src/host_tools/script_apps.rs) record these exact tool rosters. +### Conversation routing and data access + The shell supplies the desktop `Ask ` panel, app-owned `octos.*` UI and supported L0 card chat. See the [shell chat surfaces](https://github.com/OctoSense-org/OctoSense/blob/c3011a2057ec59738b79466f48ff2ad8d0e60130/docs/architecture-walkthrough.md#6-where-a-person-talks-and-where-the-answer-goes) @@ -257,60 +318,49 @@ grant and an executable owner route, plus approval where required. Contained app agents cannot call `peer_send_input` or acquire system-agent privileges through this tool route. -## 7. Run the right host + -First prepare sibling sources using Design Flow's -[native workspace instructions](https://github.com/OctoSense-org/OctoScript-App-Design-Flow/blob/main/docs/NATIVE-WORKSPACE.md). -This workspace's [`Cargo.toml`](../Cargo.toml) patches paths to `../makepad`, -`../octoscript-makepad` and `../octoscript`. Missing siblings can prevent even -Cargo metadata or a policy-only test from resolving. A consumer's top-level -patches determine its actual versions; do not mix arbitrary latest engines -with a different consumer's runtime lock. +## 7. Source reference -From App Hub. **Validation status: build, GUI and device execution unverified.** +Use this index to revisit the path traced above. The first seven files +cover admission through reply delivery; the table covers other hosts and +authoring support. -```sh -cargo build --release -p octosense-card-host -p octosense-app-hub -cargo run -p octosense-app-hub --bin hub -- help -cargo test -p octosense-app-contract -p octosense-app-policy -p octosense-app-hub -cargo test -p octosense-card-host --test cli -``` - -Run a disposable unsigned development bundle: - -```sh -MAKEPAD_HIDE_WINDOWS=1 MAKEPAD_REMOTE=8141 cargo run --release \ - -p octosense-card-host -- --bundle /absolute/path/my-app/bundle \ - --app-data /absolute/path/my-app/.local-state --allow-unsigned --stamp -``` - -That command stays in the foreground. In another terminal: - -```sh -curl -s http://127.0.0.1:8141/snap -curl -s http://127.0.0.1:8141/quit -``` +1. [`app-contract/src/lib.rs`](../crates/app-contract/src/lib.rs): the + shared, versioned data contract. `AppManifest` describes requests; + `AppPolicy` describes grants. The shell uses these declarations when + preparing an authorized octos session. +2. [`app-policy/src/policy.rs`](../crates/app-policy/src/policy.rs): resolve + the app contract plus agent requests against `HostLimits`. +3. [`app-policy/src/agent.rs`](../crates/app-policy/src/agent.rs): validate + `tools.json`, instructions and skills; construct an `AgentBundle`. +4. [`app-hub/src/gate.rs`](../crates/app-hub/src/gate.rs): produce the same + admission report for local development and publication. +5. [`app-hub/src/client.rs`](../crates/app-hub/src/client.rs): the device's + `Store`, catalog verification, installation and permission to run. +6. [`appstore/src/cardapp.rs`](../crates/appstore/src/cardapp.rs): mount a + verified app in its own shell client. +7. [`appstore/src/services.rs`](../crates/appstore/src/services.rs): route + script host requests and deliver replies. -`--stamp` writes the manifest; use a development copy. This host uses -`RefuseAllSignatures`, so `--allow-unsigned` does not make a signed manifest -verifiable. Use the store path to test signatures. `--system` changes -admission limits for first-party bundles; it does not register Mail, models -or octos. Run shell integration to test those services. +The remaining crates and supporting directories complete the delivery path: -For a native module, the standalone app binary registers `AppHostView` and -calls `open_in(module, open_json)`. In [`app-host`](../crates/app-host/src/lib.rs), -`create` validates arguments, allocates a Splash VM, supplies scoped -storage/viewport/reply handles and calls the Rust module. Event and draw -calls enter its VM. Its `ServiceExecutor` is retained but never called by -an assistant; upstream bus messages are drained. Running the same module -inside OctoSense adds the broker and agent integration. +| Path | Role and next file | +| --- | --- | +| [`card-host`](../crates/card-host/src/main.rs) | Standalone contained bundle runner; argument parsing leads to `host::run` | +| [`app-host`](../crates/app-host/src/lib.rs) | One-window host for a compiled Rust `AppModule` | +| [`app-hub-app`](../crates/app-hub-app/README.md) | Shell integration: native store, Card runner, packed system apps and icons | +| [`appstore-app`](../crates/appstore-app/src/lib.rs) | Standalone `appstore` executable using `AppHostView` | +| [`card-studio`](../crates/card-studio/src/main.rs) | Hidden `card-host` captures at glance, phone and desktop sizes; measured checks and critique payload | +| [`skills/card-studio`](../skills/card-studio/SKILL.md) | octos skill exposing card rendering and critique preparation | +| [`templates/app`](../templates/app/README.md) | Card-app scaffold with bundle metadata and contributor instructions | -To exercise distribution without publishing, use the documented -[fixture/preview commands](../crates/app-hub-app/README.md#exercise-installation-without-publishing-apps). -The fixture generates a local catalog and isolated environment settings; -only the full shell opens installed apps as clients. Native app, desktop, -Home APK and ROM build commands belong to the -[OctoSense README](https://github.com/OctoSense-org/OctoSense/blob/main/README.md). +OctoSense consumes a git revision of App Hub selected by its `Cargo.toml`. +OctoSense, App Hub and Rinx request `octosense-app-contract = "1"` from +crates.io; the consumer lock records the resolved release. This workspace +alone patches that dependency to `crates/app-contract` for development. +Cargo applies patches from the top-level workspace, so that local patch +is not inherited by a shell consuming App Hub as a dependency. ## 8. Debug by boundary From 89f3a7f01b7ba944becb9bb5221fc230b5318ea2 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Fri, 2 Oct 2026 09:40:26 -0700 Subject: [PATCH 5/5] docs: align final review corrections and companion links --- docs/CODE-WALKTHROUGH.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CODE-WALKTHROUGH.md b/docs/CODE-WALKTHROUGH.md index b3a17af..11a71d8 100644 --- a/docs/CODE-WALKTHROUGH.md +++ b/docs/CODE-WALKTHROUGH.md @@ -216,7 +216,7 @@ the app receives the service's result, not its credential. These queues use `Mutex` and a native `std::thread` timeout sweeper. The octos side uses async scheduling, explained in the -[OctoSense walkthrough](https://github.com/OctoSense-org/OctoSense/blob/c3011a2057ec59738b79466f48ff2ad8d0e60130/docs/architecture-walkthrough.md). +[OctoSense walkthrough](https://github.com/OctoSense-org/OctoSense/blob/61c668279a7c38a0f8056134d8d29e42ed715806/docs/architecture-walkthrough.md). ## 6. What declaring an app agent actually enables @@ -296,7 +296,7 @@ record these exact tool rosters. The shell supplies the desktop `Ask ` panel, app-owned `octos.*` UI and supported L0 card chat. See the -[shell chat surfaces](https://github.com/OctoSense-org/OctoSense/blob/c3011a2057ec59738b79466f48ff2ad8d0e60130/docs/architecture-walkthrough.md#6-where-a-person-talks-and-where-the-answer-goes) +[shell chat surfaces](https://github.com/OctoSense-org/OctoSense/blob/61c668279a7c38a0f8056134d8d29e42ed715806/docs/architecture-walkthrough.md#6-where-a-person-talks-and-where-the-answer-goes) for their entry points. The system agent discovers permitted prepared peers and delegates using their actual peer slug. A system request and a human request can reach the same app peer with