From ed777a04fa58a9848b83166c322920b26e7fb9a5 Mon Sep 17 00:00:00 2001 From: Edward Tan Date: Wed, 30 Sep 2026 14:22:21 -0700 Subject: [PATCH 1/3] docs: bring AI services, host services and sockets up to 2026-09-30 The shells now serve `model` (OctoSense#95), `octos.*` to contained apps behind first-use consent (#106, #120), `glance` to any app granted it (#86), and an agent with its bundle's tools and an "Ask " panel for every app that declares one (#145, #184). The docs still said no shell serves any of these. - AI-SERVICES (English and Chinese): short answer, errors (consent, turned off, unavailable), the model section, status table, the app's agent, tools and peer tools, toolbox, glance and the News walk-through, checked against OctoSense main 7082ff5 and App Hub main 0f33211. - CAPABILITIES, HOST-SERVICES, GLOSSARY, QUICKSTART, README (both) and AGENTS.md: the same facts; AI stays optional in every app, and card-host still serves none of it. - SCRIPT-API: net.web_socket is held to the host list; socket_stream and http_server are refused in a store app (makepad#30). --- AGENTS.md | 12 +- README.md | 2 +- README.zh-CN.md | 2 +- docs/AI-SERVICES.md | 283 ++++++++++++++++++++------------------ docs/AI-SERVICES.zh-CN.md | 237 +++++++++++++++---------------- docs/CAPABILITIES.md | 8 +- docs/GLOSSARY.md | 2 +- docs/HOST-SERVICES.md | 10 +- docs/QUICKSTART.md | 6 +- docs/SCRIPT-API.md | 9 +- 10 files changed, 298 insertions(+), 273 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ec671f89..83df02ad 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -48,10 +48,11 @@ patch around it here. - **Declare every host.** Every `https://` host in `main.splash` is in `network.hosts` (with `net`), unless the app legitimately needs `images` or `web`. Never `http://`. -- **No AI feature the device cannot serve.** A contained app cannot ask - OctoSense's assistant or a model yet: the `octos.*` capabilities pass the - gate, but every call answers `no service answers "octos" on this device`, - and `llm` is for system apps only. Never put a model key in an app. Read +- **Every AI feature is optional.** On an OctoSense device a store app can + call `model.complete`, and `octos.*` once the person allows its agent, but + `card-host` (and so `tools/octo run`) serves neither: every call there + answers `no service answers "…" on this device`. `llm` is for system apps + only. Never put a model key in an app. Read [docs/AI-SERVICES.md](docs/AI-SERVICES.md) before adding one, and report such a feature as not verified on a device. - **Only needed capabilities.** Each capability maps to something a screen @@ -63,7 +64,8 @@ patch around it here. for you; after signing, any edit needs stamp and sign again (human). - **Keep the bundle clean.** Only `manifest.json`, `listing.json`, the entry, artwork and screenshots go in `bundle/` (plus `tools.json`, `AGENT.md` and - `skills/` for an app that declares its own agent, which no shell runs yet: + `skills/` for an app that declares its own agent; the shells give it a peer + and its tools, but do not install `AGENT.md` or skills yet: [docs/AI-SERVICES.md](docs/AI-SERVICES.md#an-apps-own-agent)). Notes, keys, logs, review packets and `.local-state/` stay out. - **Run headless.** Start apps with `tools/octo run … --hidden` (Makepad's diff --git a/README.md b/README.md index 94dd134c..a703f72c 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ organizers; none of that is decided here. What a contestant needs from here: | **Machine** | macOS on Apple silicon is the verified platform. Windows and Linux are unverified. Rust stable (rustup), Python 3.9+ (macOS's own `/usr/bin/python3` works), git, a graphical session, about 3 GB free (the clones take about 1.9 GB, 1.3 GB of it this repository, where `--depth 1` is fine; the build about 1 GB), and network access for the first build. | | **What an app can do** | Its own storage, HTTPS requests to hosts it declares, pictures and web pages, camera, location, and Mail through a host service: [CAPABILITIES](docs/CAPABILITIES.md). The language and every API: [SCRIPT-API](docs/SCRIPT-API.md). Complete examples: the [System Apps](https://github.com/OctoSense-org/OctoSense/tree/main/apps) (News, Photos, Maps, Camera, Mail) and the [template](templates/script-app/README.md). | | **What it cannot do** | Hold a password, key or token; invent a capability or a host service (those are App Hub and shell changes); use `llm` or an `os.*` id (system apps only); be side-loaded onto a phone. `card-host` provides no host services, so a Mail-style app shows `no service answers` there. | -| **AI in the app** | Building needs none, with any coding agent or none. On the device, a store app cannot ask the assistant or a model yet: the `octos.*` capabilities pass the gate, but no OctoSense shell serves them to apps (`no service answers "octos"`). What works, what is planned, and a verified example that handles "unavailable": [docs/AI-SERVICES.md](docs/AI-SERVICES.md). | +| **AI in the app** | Building needs none, with any coding agent or none. On the device, a store app can make one-shot model calls (`model`) and, once the person allows its agent, talk to the assistant (`octos.*`); `card-host` serves neither (`no service answers "octos"`), so build the app to be complete without them. What works, what is planned, and a verified example that handles "unavailable": [docs/AI-SERVICES.md](docs/AI-SERVICES.md). | | **Demo** | The app in `card-host` (`tools/octo run`, driven over the remote bridge) and real screenshots from `tools/octo shot`. To show it inside OctoSense, run the OctoSense desktop shell against a local catalog ([PUBLISHING §4](docs/PUBLISHING.md#4-rehearse-the-store-path-locally)). | | **Submit to the App Hub** | [Publishing](#publishing): `tools/octo check` passes, `hub scan` answered, then a person signs and opens a `Submit ` issue on [OctoSense-App-Hub](https://github.com/OctoSense-org/OctoSense-App-Hub/issues). A contest entry is not automatically an App Hub submission; ask the organizers what they need. | | **Test headless** | `tools/octo run … --hidden`: the window never appears, so an agent can test your app (and several apps at once, one `--port` each) without taking over your screen. [Headless testing](#headless-testing-many-apps-no-screen). | diff --git a/README.zh-CN.md b/README.zh-CN.md index 7de184be..b4800f15 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -51,7 +51,7 @@ Agent)从一个想法(一段文字需求、一张生成的 UX 图)走到 | **机器** | 已验证的平台是 Apple silicon 上的 macOS;Windows 和 Linux 未验证。需要 Rust stable(rustup)、Python 3.9+(macOS 自带的 `/usr/bin/python3` 即可)、git、图形会话、约 3 GB 可用空间(克隆约 1.9 GB,其中本仓库 1.3 GB,可用 `--depth 1`;构建产物约 1 GB),首次构建需要联网。 | | **应用能做什么** | 自己的存储、访问已声明主机的 HTTPS 请求、图片与网页、相机、定位,以及通过宿主服务使用 Mail:[CAPABILITIES](docs/CAPABILITIES.md)。语言与全部 API:[SCRIPT-API](docs/SCRIPT-API.md)。完整示例:[系统应用](https://github.com/OctoSense-org/OctoSense/tree/main/apps)(News、Photos、Maps、Camera、Mail)和[模板](templates/script-app/README.zh-CN.md)。 | | **应用不能做什么** | 持有密码、密钥或 token;自创权限或宿主服务(那是 App Hub 和 Shell 的修改);使用 `llm` 或 `os.*` id(仅限系统应用);侧载到手机。`card-host` 不提供任何宿主服务,所以类似 Mail 的应用在其中会显示 `no service answers`。 | -| **应用中的 AI** | 开发应用不需要任何 AI 服务,可以用任何编程 Agent,也可以不用。在设备上,商店应用目前还不能调用助手或模型:`octos.*` 权限能通过准入检查,但没有任何 OctoSense Shell 向应用提供这些服务(`no service answers "octos"`)。现在能用什么、计划做什么,以及一个经过验证、能处理“不可用”状态的示例:[docs/AI-SERVICES.zh-CN.md](docs/AI-SERVICES.zh-CN.md)。 | +| **应用中的 AI** | 开发应用不需要任何 AI 服务,可以用任何编程 Agent,也可以不用。在设备上,商店应用可以进行一次性模型调用(`model`),并在用户允许其 Agent 后与助手对话(`octos.*`);`card-host` 两者都不提供(`no service answers "octos"`),所以要把应用做成不依赖它们也完整可用。现在能用什么、计划做什么,以及一个经过验证、能处理“不可用”状态的示例:[docs/AI-SERVICES.zh-CN.md](docs/AI-SERVICES.zh-CN.md)。 | | **演示** | 在 `card-host` 中运行应用(`tools/octo run`,通过远程控制桥操作),并用 `tools/octo shot` 截取真实截图。要在 OctoSense 内展示,让 OctoSense 桌面端 Shell 读取本地目录([PUBLISHING §4](docs/PUBLISHING.md#4-rehearse-the-store-path-locally))。 | | **提交到 App Hub** | [发布](#发布):`tools/octo check` 通过、回答 `hub scan` 的问题,然后由人签名,并在 [OctoSense-App-Hub](https://github.com/OctoSense-org/OctoSense-App-Hub/issues) 开一个 `Submit ` issue。参赛作品不等于自动提交到 App Hub;请向主办方确认他们需要什么。 | | **无头测试** | `tools/octo run … --hidden`:窗口不会出现,Agent 可以在不占用你屏幕的情况下测试应用(也可同时测多个应用,每个用自己的 `--port`)。见[无头测试](#无头测试同时测多个应用不占屏幕)。 | diff --git a/docs/AI-SERVICES.md b/docs/AI-SERVICES.md index e81f7374..55466eb2 100644 --- a/docs/AI-SERVICES.md +++ b/docs/AI-SERVICES.md @@ -4,11 +4,14 @@ English | [简体中文](AI-SERVICES.zh-CN.md) How a script app built here can use the assistant inside OctoSense (the octos agent kernel the shell runs), what works today, and what is planned. State as -of 2026-09-27: App Hub `main` `e8601b8`, OctoSense `main` `405139f` (which -pins App Hub `46d67e51` and octos `a6ea8505`). OctoSense `main` has since -moved to `89787ba` (octos `60cf96e6`, App Hub still `46d67e51`) and App Hub -`main` to `a72989f` (documentation only); the app-facing facts below were -re-checked there. +of 2026-09-30: App Hub `main` `0f33211`, OctoSense `main` `7082ff5` (which +pins App Hub `0f332112`). Since this page was first written (2026-09-27) the +shells gained the `model` service, the `octos` service for contained apps +behind first-use consent, `glance` for any app granted it, and an agent (a +peer and an "Ask " panel) for every app that declares one. OctoSense's +[`docs/ai-services.md`](https://github.com/OctoSense-org/OctoSense/blob/main/docs/ai-services.md) +and [`docs/architecture.md`](https://github.com/OctoSense-org/OctoSense/blob/main/docs/architecture.md) +describe the shell side. The later sections cover what is being built on top: an app's own agent declared in its bundle, the tools it exposes, the system toolbox, publishing @@ -18,7 +21,8 @@ usable as described) or **coming** (in an open pull request, named, or only in an ADR: the shape shown may change before it lands, so do not build a submission on it yet). Commands marked **✓ run** were run for this page on 2026-09-27 (macOS, Apple silicon); every other command is quoted from the -named source and marked not run. +named source and marked not run. The 2026-09-30 updates are quoted from the +named pull requests and code, not run. > **Building an app needs no AI.** Nothing in this repository calls a model > or needs an API key, and you may use any coding agent (Codex, Claude Code, @@ -37,7 +41,7 @@ The deep version, for shell and native-module developers: - [What the person sees](#what-the-person-sees) - [Errors](#errors) - [Test it](#test-it) -- [Coming: one-shot model calls (`model`)](#coming-one-shot-model-calls-model) +- [One-shot model calls (`model`)](#one-shot-model-calls-model) - [Status at a glance](#status-at-a-glance) - [An app's own agent](#an-apps-own-agent) - [The app's tools and peer tools](#the-apps-tools-and-peer-tools) @@ -51,19 +55,21 @@ The deep version, for shell and native-module developers: ## The short answer -**Today a store app cannot ask a model or the assistant anything on an -OctoSense device.** No OctoSense shell serves assistant requests to contained -apps, and `card-host` serves no host services at all. Build your app so it is -complete without AI. +**On an OctoSense device a store app can make one-shot model calls +(`model`), and can talk to the assistant (`octos.*`) once the person allows +its agent.** App Hub's `card-host`, which `tools/octo run` uses, serves no +host services at all, so both answer `no service answers "…" on this device` +there. Build your app so it is complete without AI either way: the person may +decline, and a device may have no kernel (iOS) or no provider. | You try | What happens today | | --- | --- | -| Declare `octos.turn.start` (and friends) and call it | The gate accepts the name. The call answers `no service answers "octos" on this device`, in `card-host` and in the OctoSense shells alike (verified in `card-host`, below). | -| Declare `model` and call `model.complete` | The gate accepts it (App Hub [#24](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/24), merged): a one-shot model call is **coming**. The OctoSense `model` service is a draft pull request ([OctoSense#95](https://github.com/OctoSense-org/OctoSense/pull/95)), not merged, so the call answers `no service answers "model" on this device` (verified in `card-host`). See [Coming: one-shot model calls](#coming-one-shot-model-calls-model). | +| Declare `octos.turn.start` (and friends) and call it | The gate accepts the name. In `card-host` the call answers `no service answers "octos" on this device` (verified, below). In an OctoSense shell that hosts a kernel, the first call waits for the person to allow the app's agent (`Waiting for the person to allow this app's agent (OctoSense asks the first time)`); after that the app talks to its own peer ([OctoSense#106](https://github.com/OctoSense-org/OctoSense/pull/106), [#120](https://github.com/OctoSense-org/OctoSense/pull/120), [#184](https://github.com/OctoSense-org/OctoSense/pull/184)). | +| Declare `model` and call `model.complete` | The gate accepts it (App Hub [#24](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/24)), and the OctoSense shells serve it ([OctoSense#95](https://github.com/OctoSense-org/OctoSense/pull/95), merged): a one-shot, schema-checked call answered from the person's own AI providers. `card-host` answers `no service answers "model" on this device`. See [One-shot model calls](#one-shot-model-calls-model). | | Declare `llm` | The gate accepts it, but the `llm` service manages the device's AI providers (it has no prompt method) and answers only `os.*` system apps: `llm is for OctoSense's own apps.` Do not request it. | -| Declare an `agent` in `manifest.json` | Admitted and clamped by the gate; **nothing runs it** ([An app's own agent](#an-apps-own-agent)). | -| Ship `tools.json`, `AGENT.md`, `skills/` | Admitted by App Hub `main`; **no shell loads them yet**, and the shells' older App Hub refuses a manifest with the new `agent` fields (see [Status at a glance](#status-at-a-glance)). | -| Call `glance.publish` | The service is on OctoSense `main` but answers only `os.*` apps until [OctoSense#86](https://github.com/OctoSense-org/OctoSense/pull/86) lands ([Publishing to the glance screen](#publishing-to-the-glance-screen)). | +| Declare an `agent` in `manifest.json` | Admitted and clamped by the gate. Once the person allows it, the shell gives the app its own peer, and the person can talk to it in the shell's "Ask " panel ([OctoSense#184](https://github.com/OctoSense-org/OctoSense/pull/184)). Model choice from `needs`, triggers and background runs are still **coming** ([An app's own agent](#an-apps-own-agent)). | +| Ship `tools.json`, `AGENT.md`, `skills/` | Admitted by the gate. The shell registers the bundle's tools with the app's peer and relays their calls ([OctoSense#145](https://github.com/OctoSense-org/OctoSense/pull/145), [#184](https://github.com/OctoSense-org/OctoSense/pull/184)); `AGENT.md` and skills are not installed into the peer yet. | +| Call `glance.publish` | Answered for any contained app granted the `glance` capability ([OctoSense#86](https://github.com/OctoSense-org/OctoSense/pull/86)) ([Publishing to the glance screen](#publishing-to-the-glance-screen)). | | Put a provider API key in the bundle | Never. No keys, tokens or passwords in an app ([AGENTS.md](../AGENTS.md#rules-for-every-app)). | A plain HTTPS API your app declares under `net` is just a web request, even @@ -88,14 +94,14 @@ providers. - **Approvals are the person's, in the app that asked.** The system agent never approves for an app. -Today only **native modules** the shell's host policy grants get a peer, and -the shipped policy grants one: Rinx, the Matrix client (`Policy::shipped()` -in OctoSense `crates/ai-host/src/lib.rs`). Rinx's mini-app host in turn -serves the `octos.*` names to the mini-apps a person imports into Rinx. A -contained script app installed through the App Hub gets none: the gate -admits the names, but no OctoSense shell registers an `octos` host service, -so its calls answer `no service answers "octos"`. Script apps get a peer in -the plan below. +**Native modules** the shell's host policy grants get a peer (the shipped +policy grants Rinx, the Matrix client: `Policy::shipped()` in OctoSense +`crates/ai-host/src/lib.rs`), and Rinx's mini-app host serves the `octos.*` +names to the mini-apps a person imports into Rinx. A **contained script app** +gets its own peer too (`card.`), through the shell's `octos` host +service ([OctoSense#106](https://github.com/OctoSense-org/OctoSense/pull/106)), once the person allows its agent at first +use ([#120](https://github.com/OctoSense-org/OctoSense/pull/120), [#184](https://github.com/OctoSense-org/OctoSense/pull/184)). `OCTOSENSE_CONTAINED_APPS=1` skips the +question for every app (a developer override) and `0` turns it off. ## The assistant capabilities @@ -111,12 +117,15 @@ Four exact names, each its own consent (`KNOWN_CAPABILITIES` in App Hub | `octos.turn.start` | `octos.turn.start` | `{text}` (1 byte to 32 KiB) | `{turn_id, text}`, the reply, once the turn ends | Ask the assistant to work for it, using the device's AI settings | | `octos.turn.interrupt` | `octos.turn.interrupt` | `{}` | stops the running turn | Stop assistant work it started | -The argument and answer shapes are those of the one host that serves these -names today, Rinx's mini-app host (`src/host/octos.rs` in -[hagency-org/Rinx](https://github.com/hagency-org/Rinx), over OctoSense's -`crates/app-peers`). Other arguments are refused (`Unsupported Octos -arguments`): an app supplies text, never a session, profile, provider, model -or approval decision. One turn runs at a time per app instance, and a turn +The argument and answer shapes are those of the two hosts that serve these +names, both over OctoSense's `crates/app-peers`: the OctoSense shells' `octos` +service for contained apps (`crates/ai-host/src/contained.rs`) and Rinx's +mini-app host (`src/host/octos.rs` in +[hagency-org/Rinx](https://github.com/hagency-org/Rinx)). Other arguments are +refused (`Unsupported Octos arguments`): an app supplies text (in the +OctoSense shells, also `trigger`, one of `person`, `app` or `incoming`, and +`from`, saying what started the turn), never a session, profile, provider, +model or approval decision. One turn runs at a time per app instance, and a turn gives up after 180 s. ## A minimal call, and handling "unavailable" @@ -164,14 +173,16 @@ runtime `65d30a09`), clicking the button over the remote bridge: | `["octos.session.open", "octos.turn.start"]` | `Assistant unavailable: no service answers "octos" on this device` | | `["storage"]` | `Assistant unavailable: this app was not granted "octos", which "octos.session.open" needs` | -The OctoSense shells run the same App Hub dispatch and register no `octos` -service either (they register `mail`, `llm`, `news` and `glance`), so a store -app hears the same `no service answers` there. +An OctoSense shell that hosts a kernel answers differently: the first call +asks the person to allow the app's agent, and then the app talks to its own +peer ([OctoSense#106](https://github.com/OctoSense-org/OctoSense/pull/106), [#184](https://github.com/OctoSense-org/OctoSense/pull/184); not run for this page). See +[Errors](#errors) for what each refusal says. -**Should you ship this today?** Only if the app is complete without it. A -reviewer asks about grants nothing on screen needs (`hub scan`), and every -`octos.*` line appears on the store's permission list. If you keep the call, -say in your listing and your report that it does nothing on today's devices. +**Should you ship this today?** Only if the app is complete without it: the +person may decline, the device may have no kernel or no provider, and +`tools/octo run` never answers. A reviewer asks about grants nothing on screen +needs (`hub scan`), and every `octos.*` line appears on the store's permission +list. ## What the person sees @@ -184,7 +195,9 @@ say in your listing and your report that it does nothing on today's devices. Settings → AI providers on the desktop, OctoSense Settings → Accounts → AI providers on a phone. - **Tool approvals** the assistant raises go to the person, in the app that - asked, on the host's own controls (today that host is Rinx); the system + asked, on the host's own controls (the OctoSense shells' approval sheets, + [OctoSense#120](https://github.com/OctoSense-org/OctoSense/pull/120) and + [#145](https://github.com/OctoSense-org/OctoSense/pull/145); Rinx's own for its mini-apps); the system agent never answers them. A script app cannot approve anything: no argument carries a decision. @@ -193,9 +206,12 @@ say in your listing and your report that it does nothing on today's devices. | `r.error` | Meaning | What your app does | | --- | --- | --- | | `this app was not granted "octos", which "" needs` | The manifest does not list that exact name | Add it to `capabilities`, or remove the call | -| `no service answers "octos" on this device` | This host does not serve the assistant to apps (today: every OctoSense shell and `card-host`) | Show "unavailable" and carry on | -| `no service answers "model" on this device` | No `model` service on this host (today: every OctoSense shell and `card-host`) | The same | -| `: ` from `model.complete` (**coming**, OctoSense#95), `` one of `capability`, `no_provider`, `rate`, `budget`, `bad_request`, `invalid_output`, `too_large`, `provider` | The `model` service refused the call ([details](#what-octosense95-adds-coming)) | Show the sentence; keep the app usable without the model | +| `no service answers "octos" on this device` | This host does not serve the assistant to apps (`card-host`, or a shell built without a kernel) | Show "unavailable" and carry on | +| `Waiting for the person to allow this app's agent (OctoSense asks the first time)` | The person has not allowed the app's agent yet; the shell is asking | Show it; the person's answer decides the next call | +| `The assistant is turned off for apps on this device` | The device turned the assistant off for apps (`OCTOSENSE_CONTAINED_APPS=0`) | Show "unavailable" and carry on | +| `The assistant is not available on this device` | The shell could not start the app's peer | The same | +| `no service answers "model" on this device` | No `model` service on this host (`card-host`) | The same | +| `: ` from `model.complete`, `` one of `capability`, `no_provider`, `rate`, `budget`, `bad_request`, `invalid_output`, `too_large`, `provider` | The `model` service refused the call ([details](#the-model-service)) | Show the sentence; keep the app usable without the model | | `Unsupported Octos arguments` | An argument other than `text` (turn start) or anything at all (the others) | Send only `{text}` or `{}` | | `Provide text (at most 32 KiB)` | Empty or oversized prompt | Check before sending | | `This app already has an assistant turn running` | One turn at a time | Disable the button while waiting, or interrupt first | @@ -213,22 +229,20 @@ There is no per-app quota API. Budgets are the host's (planned, below). - **In the OctoSense desktop:** rehearse the store path ([PUBLISHING §4](PUBLISHING.md#4-rehearse-the-store-path-locally)). To give the shell a kernel and a provider, see OctoSense - [`docs/ai-services.md` § Run and test locally](https://github.com/OctoSense-org/OctoSense/blob/main/docs/ai-services.md#run-and-test-locally); - your app still hears `no service answers "octos"` there today. -- **The one host that answers today** is Rinx's mini-app host, for bundles a - person imports into Rinx after review (a Matrix sign-in, Rinx's own - assistant peer): [Rinx `examples/miniapps`](https://github.com/hagency-org/Rinx/tree/main/examples/miniapps). + [`docs/ai-services.md` § Run and test locally](https://github.com/OctoSense-org/OctoSense/blob/main/docs/ai-services.md#run-and-test-locally). + There your app's first `octos.*` call asks the person to allow its agent. +- **Rinx's mini-app host** also answers `octos.*`, for bundles a person + imports into Rinx after review (a Matrix sign-in, Rinx's own assistant + peer): [Rinx `examples/miniapps`](https://github.com/hagency-org/Rinx/tree/main/examples/miniapps). It is not the App Hub install path, and it refuses a bundle that declares an `agent`. Not re-run for this page. -## Coming: one-shot model calls (`model`) +## One-shot model calls (`model`) App Hub `main` admits a second, narrower path ([App-Hub#24](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/24), -merged): the `model` capability, for the shell's `model` host service. As -App Hub describes it (the OctoSense service is -[OctoSense#95](https://github.com/OctoSense-org/OctoSense/pull/95), a draft -that is not merged, so none of this runs yet): +merged): the `model` capability, served by the OctoSense shells' `model` host +service ([OctoSense#95](https://github.com/OctoSense-org/OctoSense/pull/95), merged 2026-09-28): - `host.request("model.complete", {task, input, schema, class}, fn(r){…})`, with `class` `fast` or `strong`. The host picks the model from the @@ -243,19 +257,16 @@ that is not merged, so none of this runs yet): the AI provider you configured, for one-off answers within a daily budget; it never sees your API keys." -Today the gate passes it (`grants: capabilities {"model"}`) and every call +The gate passes it (`grants: capabilities {"model"}`), and the shells' App +Hub pin knows the name. `card-host` has no `model` service: a call there answers `no service answers "model" on this device` (run in `card-host` at -App Hub `e8601b8`). The shells' pinned App Hub (`46d67e51`) does not know the -name, so today's shells refuse a manifest that requests it; the pin moves to -an App Hub with `model` in -[OctoSense#70](https://github.com/OctoSense-org/OctoSense/pull/70) (open). +App Hub `e8601b8`). -### What OctoSense#95 adds (coming) +### The `model` service -The service in #95 (`apps/ai-providers/host-service/src/complete/`, crate -`octosense-llm-service`, registered by `crates/ai-host` next to `llm`) fixes -the shape. It is a draft and may change before it lands; do not ship a -submission that depends on it yet. It also adds ADR 0002 §14, "Direct +The service (`apps/ai-providers/host-service/src/complete/`, crate +`octosense-llm-service`, registered by `crates/ai-host` next to `llm`; +[OctoSense#95](https://github.com/OctoSense-org/OctoSense/pull/95)) has this shape. #95 also added ADR 0002 §14, "Direct one-shot model calls", which keeps an app's own agent (below) the main path for anything with tools, research, memory or approvals. @@ -286,7 +297,7 @@ for anything with tools, research, memory or approvals. - The service also checks the app's own manifest for `model`, behind the Card runner's gate. -A call as #95 shapes it (not run: no shell serves `model` yet; the literal +A call (not run for this page; the literal syntax follows the Photos bundle, space-separated lists and maps): ```splash @@ -305,50 +316,50 @@ host.request("model.complete", { ## Status at a glance -As of 27 Sep 2026. **available** means merged on `main` of the repository +As of 30 Sep 2026. **available** means merged on `main` of the repository named; **coming** means an open pull request (named) or only an ADR. | Feature | Status | Pull requests, source | | --- | --- | --- | | Apps reach AI only through host services and the app-peer broker, never the kernel, a provider or a key | **available** (the rule) | OctoSense [`AGENTS.md`](https://github.com/OctoSense-org/OctoSense/blob/main/AGENTS.md) rules 3 and 4, [`crates/app-peers`](https://github.com/OctoSense-org/OctoSense/tree/main/crates/app-peers) | | `octos.*` for native modules the host policy grants (Rinx), and through Rinx's mini-app host for bundles imported into Rinx | **available** | OctoSense `crates/ai-host` (`Policy::shipped()`); [Rinx](https://github.com/hagency-org/Rinx) `src/host/octos.rs` | -| `octos.*` for a contained script app in OctoSense | **coming**: the gate admits the names, no shell serves them (`no service answers "octos"`) | OctoSense [ADR 0002](https://github.com/OctoSense-org/OctoSense/blob/main/docs/adr/0002-event-driven-app-agents.md) (Proposed), first for News ([#61](https://github.com/OctoSense-org/OctoSense/issues/61)) | +| `octos.*` for a contained script app in OctoSense | **available** where the shell hosts a kernel (not iOS), once the person allows the app's agent at first use | OctoSense [#106](https://github.com/OctoSense-org/OctoSense/pull/106), [#120](https://github.com/OctoSense-org/OctoSense/pull/120), [#184](https://github.com/OctoSense-org/OctoSense/pull/184) | | `llm`: the person's AI providers, masked keys, host sheets | **available**, system apps (`os.*`) only; no prompt method | OctoSense [`apps/ai-providers/host-service`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/ai-providers/host-service) | -| `model.complete`: one-shot, schema-checked model call | **coming**: capability merged in App Hub ([App-Hub#24](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/24)); service in [OctoSense#95](https://github.com/OctoSense-org/OctoSense/pull/95) (draft); the shells' App Hub pin moves in [OctoSense#70](https://github.com/OctoSense-org/OctoSense/pull/70) | [above](#coming-one-shot-model-calls-model) | -| An app's own agent in the bundle: `agent` (profile, model needs, triggers, skills), `tools.json`, `AGENT.md`, `skills/` | **available** in the App Hub gate ([App-Hub#18](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/18)); **coming** in the shells (the pin moves in [OctoSense#86](https://github.com/OctoSense-org/OctoSense/pull/86)); nothing runs the agent yet (ADR 0002 M2, M3) | [An app's own agent](#an-apps-own-agent) | +| `model.complete`: one-shot, schema-checked model call | **available**: the capability ([App-Hub#24](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/24)) and the service ([OctoSense#95](https://github.com/OctoSense-org/OctoSense/pull/95)), in the shells' App Hub pin | [above](#one-shot-model-calls-model) | +| An app's own agent in the bundle: `agent` (profile, model needs, triggers, skills), `tools.json`, `AGENT.md`, `skills/` | **available** in the App Hub gate ([App-Hub#18](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/18)) and the shells: a peer and the "Ask " panel once the person allows it ([OctoSense#184](https://github.com/OctoSense-org/OctoSense/pull/184)); `AGENT.md` and skills are not installed into the peer yet | [An app's own agent](#an-apps-own-agent) | | The host picking the model from `needs` and `tier`; triggers and `background` firing | **coming** (ADR 0002 step 2, M3) | [The manifest's `agent`](#the-manifests-agent) | -| App tools registered with the app's peer (`peer/tools/register`, `peer/tool/call`) | **coming**: [octos#2567](https://github.com/octos-org/octos/pull/2567), draft, changes requested; no OctoSense pull request yet | [The app's tools and peer tools](#the-apps-tools-and-peer-tools) | -| In-app conversation with the app's agent, run-time approvals, app memory | **coming**: ADR 0002 §9–10 (M7); only the approval declarations are checked today | [What is enforced where](#what-is-enforced-where) | -| System toolbox: templates, `workflow.run`, `workflow.fork`, the `research` module | **coming**: [OctoSense#82](https://github.com/OctoSense-org/OctoSense/pull/82), draft; the `research` and `crawl` capabilities are not in App Hub | [The system toolbox](#the-system-toolbox) | -| `news` host service (a data service, no model) | **available**, system apps only; the `news` capability is on App Hub `main` but not in the shells' pin | OctoSense [`apps/news/host-service`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/news/host-service) | -| `glance.publish`, `glance.withdraw`, `glance.list` (the service) | **available** ([OctoSense#72](https://github.com/OctoSense-org/OctoSense/pull/72)), `os.*` contained callers only | [Publishing to the glance screen](#publishing-to-the-glance-screen) | -| The `glance` capability | **available** in App Hub ([App-Hub#22](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/22)); **coming** in the shells ([OctoSense#86](https://github.com/OctoSense-org/OctoSense/pull/86)) | [Who may publish](#who-may-publish) | +| App tools registered with the app's peer (`peer/tools/register`, `peer/tool/call`) | **available**: the kernel side ([octos#2567](https://github.com/octos-org/octos/pull/2567)) and the shell registering the bundle's tools and relaying their calls ([OctoSense#145](https://github.com/OctoSense-org/OctoSense/pull/145), [#184](https://github.com/OctoSense-org/OctoSense/pull/184)) | [The app's tools and peer tools](#the-apps-tools-and-peer-tools) | +| In-app conversation with the app's agent, run-time approvals, app memory | Conversation **available** in the shell's "Ask " panel ([OctoSense#184](https://github.com/OctoSense-org/OctoSense/pull/184)); approvals on the shell's sheets ([#120](https://github.com/OctoSense-org/OctoSense/pull/120), [#145](https://github.com/OctoSense-org/OctoSense/pull/145)); app memory **coming** (ADR 0002 §9, M7) | [What is enforced where](#what-is-enforced-where) | +| System toolbox: templates, `workflow.run`, `workflow.fork`, the `research` module | Templates **available** ([OctoSense#82](https://github.com/OctoSense-org/OctoSense/pull/82), `crates/toolbox`) and the `research` and `crawl` capabilities in App Hub ([App-Hub#26](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/26)); granting the toolbox to app agents is **coming** ([OctoSense#64](https://github.com/OctoSense-org/OctoSense/issues/64); the `toolbox-peers` build feature is off in the shipped shells) | [The system toolbox](#the-system-toolbox) | +| `news` host service (a data service, no model) | **available**, system apps (`os.*`) only | OctoSense [`apps/news/host-service`](https://github.com/OctoSense-org/OctoSense/tree/main/apps/news/host-service) | +| `glance.publish`, `glance.withdraw`, `glance.list` (the service) | **available** ([OctoSense#72](https://github.com/OctoSense-org/OctoSense/pull/72)) to any contained app granted `glance` ([OctoSense#86](https://github.com/OctoSense-org/OctoSense/pull/86)) | [Publishing to the glance screen](#publishing-to-the-glance-screen) | +| The `glance` capability | **available** in App Hub ([App-Hub#22](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/22)) and the shells ([OctoSense#86](https://github.com/OctoSense-org/OctoSense/pull/86)) | [Who may publish](#who-may-publish) | | `sys.digest(app:, id:, fields:)` L0 source | **coming**: [OctoScript#40](https://github.com/OctoSense-org/OctoScript/pull/40), [OctoScript-Makepad#50](https://github.com/OctoSense-org/OctoScript-Makepad/pull/50), [OctoSense#87](https://github.com/OctoSense-org/OctoSense/pull/87) | [Cards bound to findings](#cards-bound-to-findings-sysdigest) | | Render and critique a card: `card-studio`, `card-host --remote` | **available** (App Hub `main`, [App-Hub#19](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/19)); run by an app's agent **coming** (M6) | [Card levels and render-and-critique](#card-levels-and-render-and-critique) | -In one line: today a store app can **declare** an agent that passes the gate, -but nothing in a shell runs it, calls its tools, calls a model for it or lets -it publish; the pieces that will are the open pull requests above. +In one line: a store app can call `model.complete`, publish glance cards +when granted `glance`, and, once the person allows its agent, talk to the +assistant through its own peer, whose tools the shell registers; model choice +from `needs`, triggers, background runs, app memory and the system toolbox +for app agents are still coming. What an app author can do today: - Build the app's own screens so they are complete without AI, and show "unavailable" as a normal state. - Declare an agent (`agent`, `tools.json`, `AGENT.md`, skills) that passes - `hub check` on App Hub `main`, knowing no shell runs it yet (and that - today's shells refuse its manifest; see below). + `hub check`, knowing the shells give it a peer and register its tools but + do not yet install `AGENT.md` or skills, choose its model or fire its + triggers. - Write and render L0 cards with `card-studio`, and design them around `sys.digest` once OctoScript#40 lands. **Version skew to know about.** `tools/octo check` runs the App Hub checkout -beside this repository (`main`). The OctoSense shells still pin App Hub -`46d67e51`, which predates the `glance`, `news` and `model` capabilities and the new -`agent` fields (`model`, `background`, `triggers`, `instructions`, `skills`). -Manifests refuse unknown fields, so a bundle that uses any of them passes -`octo check` but is refused by today's shells. Leave them out of a bundle you -want to open in OctoSense now. Whether the shells' older App Hub admits a -bundle that carries `tools.json`, `AGENT.md` or `skills/` was not tested, and -nothing would use them there. +beside this repository (`main`). The OctoSense shells pin an App Hub commit of +their own (`0f332112` on 2026-09-30, in OctoSense's `native-apps.json`), which +can lag App Hub `main`. Manifests refuse unknown fields, so a field newer than +the shells' pin passes `octo check` but is refused by the shells until their +pin moves. If you want to prepare, draft `tools.json` and `AGENT.md` outside `bundle/`, from App Hub's News example @@ -358,11 +369,13 @@ from App Hub's News example **available** in the App Hub gate since [App-Hub#18](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/18) -(merged 2026-09-27); **coming** everywhere else. OctoSense's shells pin an App -Hub from before #18, so their Card runner refuses these manifest fields as -unknown until the pin moves (OctoSense#86 moves it), and no shell installs -`AGENT.md` or skills into a peer, selects a model or fires a trigger yet (ADR -0002, Implementation step 2). +(merged 2026-09-27), and in the shells' App Hub pin. Since +[OctoSense#184](https://github.com/OctoSense-org/OctoSense/pull/184) (2026-09-30) the shell gives an app that declares an +agent (or `octos.*`, or ships `tools.json`) its own peer once the person +allows it, registers the bundle's tools with it, and lets the person talk to +it in the "Ask " panel. No shell installs `AGENT.md` or skills into the +peer, selects a model or fires a trigger yet (ADR 0002, Implementation step +2). The contract is App Hub's [PUBLISHING § The app's agent and tools](https://github.com/OctoSense-org/OctoSense-App-Hub/blob/main/docs/PUBLISHING.md#the-apps-agent-and-tools); @@ -390,7 +403,7 @@ What OctoSense | 11 | The system agent tunes app agents with a versioned overlay; it never edits the pinned `AGENT.md`. | | 12 | Script apps and native modules follow one model; only where rules are enforced differs. | | 13 | Least privilege: tools, network, files, memory, secrets, risk, model, budgets, output, control. | -| 14 | A narrow, direct, one-shot model call for bounded jobs (`model.complete`, [above](#coming-one-shot-model-calls-model)); added in OctoSense#95, a draft. | +| 14 | A narrow, direct, one-shot model call for bounded jobs (`model.complete`, [above](#one-shot-model-calls-model)); added in OctoSense#95 (merged). | ### The bundle @@ -521,8 +534,8 @@ is closed, on a schedule; only if you allow it, and you can turn it off." and | Part | Status | | --- | --- | | Declarations (fields, sizes, names, schemas, risk, confirm) | **available**: the App Hub gate refuses or warns | -| The approval gate at run time (kernel); approve, edit or decline in the app's conversation | **coming**: octos#2567 (kernel side), ADR 0002 §10 / M7 (the shell's conversation) | -| In-app conversation with the app's agent | **coming**: ADR 0002 §10, M7; no pull request yet | +| The approval gate at run time (kernel); approve, edit or decline | **available**: the kernel side ([octos#2567](https://github.com/octos-org/octos/pull/2567)) and the shell's approval sheets ([OctoSense#120](https://github.com/OctoSense-org/OctoSense/pull/120), [#145](https://github.com/OctoSense-org/OctoSense/pull/145)); approvals stay on those sheets, not in the app's conversation ([#184](https://github.com/OctoSense-org/OctoSense/pull/184)) | +| In-app conversation with the app's agent | **available** in the shell's "Ask " panel ([OctoSense#184](https://github.com/OctoSense-org/OctoSense/pull/184)) | | Memory in `app//…`, promotion by rule | **coming**: ADR 0002 §9, M7. There is no manifest field; memory rules are prose in `AGENT.md` | | Overlays by the system agent | **coming**: ADR 0002 §11, M8 | @@ -564,18 +577,19 @@ by the App Hub gate (`crates/app-policy/src/agent.rs`): descriptions. - `implemented_by`: `host-service` (native code that holds data, network or secrets) or `app` (the app's script, for tools that only reshape its own - data). How a call reaches a script app's own implementation is not - specified yet. + data). The shell runs a `host-service` tool on the host service of its + namespace, with the app's identity, as the app's own `host.request` would; + it refuses an `app` tool for now (` runs in the app's own script; + open the app to use it`; OctoSense `crates/shell/src/host_tools/script_apps.rs`). - `background`, `shareable`, `private_data`, `confirm`: see [An app's own agent](#approvals-risk-and-confirm). -How the shell will hand them to the app's peer is **coming**: +The shell hands them to the app's peer: the kernel side is [octos#2567](https://github.com/octos-org/octos/pull/2567) ("host-registered -tools per app peer with tool-list and risk enforcement", UPCR-2026-035), -draft, **changes requested** (the open point is whether credential binding, -octos#2556, must land first). The OctoSense side, the shell registering an -app's `tools.json` for its peer, has no pull request yet. Per #2567 (names -may change): +tools per app peer with tool-list and risk enforcement", UPCR-2026-035, +merged 2026-09-29), and the shell registers an app's `tools.json` for its +peer and relays the calls ([OctoSense#145](https://github.com/OctoSense-org/OctoSense/pull/145), [#184](https://github.com/OctoSense-org/OctoSense/pull/184)). Per +#2567: | Method | Direction | Shape | | --- | --- | --- | @@ -593,11 +607,14 @@ or outward) with `confirm: host` waits for a kernel approval; with ## The system toolbox -**coming**: [OctoSense#82](https://github.com/OctoSense-org/OctoSense/pull/82) -(draft, `crates/toolbox`, crate `octosense-toolbox`); "the shells do not link -it yet". The `research` and `crawl` capabilities do not exist in App Hub (the -gate refuses them: `policy: app dev.example.brief requests unknown capability -"research"`, **✓ run**), and `crawl` / `deep_crawl` is not implemented. +The templates are **available** ([OctoSense#82](https://github.com/OctoSense-org/OctoSense/pull/82), merged: +`crates/toolbox`, crate `octosense-toolbox`), and App Hub has the `research` +and `crawl` capabilities ([App-Hub#26](https://github.com/OctoSense-org/OctoSense-App-Hub/pull/26)). +Granting the toolbox to an app's agent is **coming** +([OctoSense#64](https://github.com/OctoSense-org/OctoSense/issues/64)): the +shells' `toolbox-peers` build feature is off in the shipped builds, and +`crawl` / `deep_crawl` is not implemented (the toolbox's one module is +`research`). An app's agent never searches, crawls or drives a browser itself. It is granted toolbox tools, and the host runs them outside the app, under the @@ -657,10 +674,10 @@ through `host.request`. url, title, source, language, published_at, retrieved_at, evidence_sha256, via`. A URL in the output that the host did not retrieve fails the run. - **Results** are written to `/toolbox/runs/