Repository navigation
docs(adr): 0004 native apps, app agents and cross-app work (accepted) - #110
Conversation
A new ADR, 0004, and dated amendments to ADR 0002 and Home ADRs 0002 and 0004 that point to it. ADR 0004 records: - two manifests: system-apps.json for script apps, a new native-apps.json (and a generator with --check) in place of five hand edits; the native News, Maps and Photos crates are deleted - hosting per target: own process on macOS, Windows and Linux with Vulkan+Wayland; in-process on Linux without them, on mobile and wasm - the trust boundary: native apps first-party only; an OS sandbox per process app; a process app reaches its agent only through the shell, which relays and checks everything (ADR 0003: external clients never reach app agents) - an app agent for every app, native or script, with consent at first use; the peer link for process apps - verified octos facts: peers are sessions in one kernel process; the 8-peer limit is per peer/prepare call; master and peers talk through the inbox and the file blackboard; and the octos#2567 gap (a system-agent turn on an app peer gets none of the app's context) - cross-app work: the owning app's agent makes changes; the shell routes shareable tool calls - approvals by the person only, live or through standing rules the shell enforces, capped at time-boxed rules - app storage: one layout for every app, declared in the manifest; the agent's workspace is its account folder; secrets never in a jail - toolbox grants per capability and no command execution; developer mode grants everything for building apps fast - worked examples: Mail fact-check; Calendar + Mail meeting - open: D1 (read-only questions may use shareable read tools directly) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review of ADR 0004, with the maintainer's decisions on the open points:
Minor:
🤖 Generated with Claude Code |
…approvals - §1: app agents and the system agent may call another app's tools when the calling manifest asks and the shell grants them (at install for script apps, in native-apps.json for native apps); the shell registers, routes, marks and checks each call and authorizes it against the grants with no second agent-level consent. Replaces "the system agent never holds app tools". - §6: toolbox tools reach agents as host-routed tools: workflow.run and workflow.fork; toolbox.search and toolbox.web_read with research; toolbox.deep_crawl with crawl; not octos's deep_research. Registration is additive, host-routed tools stay out of external turns (octos#2601), ownership is per connection, and system-agent input arrives as peer/input (octos#2567). - §10: the shell renders every approval; an agent's text never approves; each line shows owning app, tool, exact args and the calling app; standing rules keyed to (owning app, tool). - §12: the system agent's tool set is defined and enforced with a test; today it gets the full default set, shell included. - §4, §13, Examples, Implementation, M5 and the amendment list follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- D1 replaced (§7): app agents and the system agent may call other apps' granted tools; granted at install for script apps, in native-apps.json for native apps; the shell registers, marks, routes and authorizes each call against the grants, with no second agent-level consent. - §2 and the plan: the Terminal is the only process app for now; App Hub stays in-process (it hosts the Card runner); Rinx stays in-process until the peer link and sandboxes exist. - §6: names the peer/input event agreed on octos#2567 and what happens when the host is absent; replaces the interim shell relay. - §8: the shell renders every approval sheet; an agent's text is never an approval surface; standing rules keyed to (owning app, tool), with the calling app shown. - §12 and plan step 4: define the system agent's tool set (no shell), enforce it in octos or host config, with a test. - §13: Talk to Octos external clients never get developer grants or dev.run; banner and audit unchanged. - §11 and the plan: the Rinx storage move (#101) and App Hub pin moves go through the tagged-Rinx rule and the lockstep fix (hagency-org/Rinx#37). - Context, §4, §12 toolbox names, the worked example and Consequences follow; octos#2601 added to Relates to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Two commits on top of 4498fa5 put the review decisions above into the text: 6488e09: ADR 0002 amendments
50d3131: ADR 0004 edits
Open for review:
The ADR READMEs are unchanged: no titles or statuses changed. 🤖 Generated with Claude Code |
…-out - §5: PeerToolCall carries account, context_id and client, stamped by the shell from its context table; the app never supplies them on a call. §9: Rinx checks a mini app's grants against `client`. - §11: request contexts are fenced to contexts/<id>/, so they read account data through shell-executed host read tools (files.list/read/search); the shell never passes an explicit context cwd. Ask octos for a read-only view. - §6: host-driven turns carry a generic_tools allowlist without ask_user_question, so the shell registers host.ask and routes it. Ask octos to keep ask_user_question on those turns. - §11: sign-out suspends the agent (contexts closed, calls refused, no turns), never peer_close; account removal and uninstall need a host-only peer/purge upstream. - Context, Gaps, ADR 0002's amendment and the plan follow. Checked against octos#2567 head 7af6e0ce. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…est and grant Maintainer decisions on #110, replacing 6488e09/50d3131's "the app's own sheet only for calls from its own agent while the person is present" and the "app agents get no web_search/deep_search" text. Approvals (ADR 0002 §1, §10, §12, §13, examples, plan, amendment; ADR 0004 §5, §7, §8, §9, Consequences, plan): - The shell is the single path and authority for every app tool call, from the owning app's agent, another app's agent or the system agent. - confirm: host: the shell draws the sheet. confirm: app: the shell hands the confirmation to the owning app, which shows its own sheet for every caller; PeerToolCall gains `caller` so the sheet can show it. - App not running or nobody present: waits or is refused visibly (#2567). Tools (ADR 0002 §6, §13, plan, amendment; ADR 0004 Gaps, §6, §12, plan): - App agents get whatever their manifest declares and the person grants at install, octos's web_search/deep_search and command execution included; no hard-coded exclusions. The shell sets generic_tools from the grant. External clients keep their fixed allowlist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
91cc69f applies two maintainer decisions to ADR 0002 and ADR 0004:
🤖 Generated with Claude Code |
…end confirm: host Three maintainer answers on #110: - The system agent may be granted command execution, like app agents: off unless the person grants it in Settings, each command approved live through the shell. Its tool set is its grants, enforced by the shell and tested (ADR 0002 §12 and amendment; ADR 0004 §12, Consequences, plan 4). - The Terminal's AI may type commands; each goes through the shell with a live approval of the exact command and stays auto_approvable: false (ADR 0004 §10; consistent with makepad#41). - mail.send is confirm: host: the shell draws its sheet, may batch it, and standing rules may answer it (ADR 0002 §12 and Mail row; ADR 0004 §8 and the Calendar/Mail example). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
38c021e applies three more maintainer answers:
🤖 Generated with Claude Code |
Maintainer decision on #110: developer mode overrides all approvals, auto_approvable: false included (Terminal commands, granted command execution, deletes, payments); there is no live sheet in developer mode. - ADR 0004 §13 says so explicitly and restates the guardrails that stay: banner, audit of every call and command, never for external clients, development-build or explicit-flag gate, developer profile. - ADR 0004 §8, §10 and §12 and ADR 0002 §10, §12 and the §10 amendment qualify live approval and auto_approvable: false with "outside developer mode" and a reference to ADR 0004 §13. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
99569a1: developer mode overrides every approval, including
🤖 Generated with Claude Code |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ADR 0004 §1 (#110): the script apps are the only versions. The native crates were kept "for comparison" behind `app-news`, `app-photos` and `app-maps`; nothing shipped them. - apps/{news,maps,photos}/native, their workspace members and pins, the shell's optional deps, `app-*` features and place in `mobile-apps`, the desktop and phone forwards, and their linked_modules() lines. The makepad-map-nav pin and patch go with Maps (nothing else used it). - Photos' sample library, which Home mounts into the script app, moves to apps/photos/resources/ with its provenance (SOURCES.md, generated-scenes.json); phone/system-apps.json points there. The native crate's catalog and icons go. - The phone catalogs' native News/Maps/Photos rows, phone.yml's builds and tests of the three crates, phone/docs/{photos,maps}.md, and the README and ADR mentions (both languages). Cargo.lock updated by cargo metadata (four packages removed). Verified: cargo check --locked -p octosense; from phone/: cargo check --locked -p octosense-home --features mobile-apps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… process on macOS and Windows ADR 0004 §2 and §10 (#110). A linked native app the person has not switched is now hosted as its manifest entry declares for this target (native_apps.rs, `NativeApp::on_this_target`), replacing the hard-coded "robrix | finance | terminal are modules" rule (robrix and finance are not linked by any build): - Terminal: its own process on macOS and Windows; on Linux only with a Vulkan build (`MAKEPAD=vulkan`, new `makepad_vulkan` cfg in the shell's build.rs) in a Wayland session; in-process on phones. A crash in it no longer takes the shell down. - A declared process falls back to in-process where it has no process form (`apps::process_form`: its launcher row resolves neither to a checkout to `cargo run` from nor to a sibling binary). - App Hub, Rinx and AppCard are modules everywhere; Reference and Sheets keep their process default on the desktop. - `terminal: Module|Process` (and any `<id>: ...`) in wm/apps.splash and `--module <id>` still win. The process is found the way every catalog app is (clients.rs): out of a checkout, `cargo run --release --manifest-path .sources/makepad/Cargo.toml -p makepad-terminal --bin terminal --target-dir <home>/build/makepad`; otherwise the `terminal` binary beside `octosense`. Release packages do not ship that binary yet: that depends on OctoSense #94; until then a packaged build falls back to the in-process Terminal. The standalone terminal binary publishes `run` on the AI services bus. The bus now withholds it (ai_bus::WITHHELD_TOOLS, keyed by the app id the shell launched the client as): stripped from the registration and replay, and a call to it is dropped, so the assistant gets read_screen and read_scrollback only in either hosting. Behaviour changes: Terminal opens as a process on macOS/Windows; Rinx (default) and AppCard (opt-in) now open in-process without `--module` (they have no process form, so before they were not launchable on the desktop without the flag). Verified on macOS: cargo build --locked -p octosense; tools/check-shell-graph.sh -p octosense and -p octosense-home; cargo test --locked -p octosense-shell --features app-terminal: 348 passed; from phone/: cargo check --locked -p octosense-home --features mobile-apps, cargo test --locked --features mobile-apps -p octosense-shell: 358 passed; native_apps.py --check; tools unittests. Hidden desktop (MAKEPAD_HIDE_WINDOWS, MAKEPAD_REMOTE, scratch OCTOSENSE_HOME, MAKEPAD_WM_TEST_APP=terminal): "launched terminal as client 1" (a process, not "in-process"), cargo built the `terminal` bin into the scratch home, first frame drawn in the tile, zsh running under it, typed text reached it; /quit ended both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ADR 0004 §1 (#110): the script apps are the only versions. The native crates were kept "for comparison" behind `app-news`, `app-photos` and `app-maps`; nothing shipped them. - apps/{news,maps,photos}/native, their workspace members and pins, the shell's optional deps, `app-*` features and place in `mobile-apps`, the desktop and phone forwards, and their linked_modules() lines. The makepad-map-nav pin and patch go with Maps (nothing else used it). - Photos' sample library, which Home mounts into the script app, moves to apps/photos/resources/ with its provenance (SOURCES.md, generated-scenes.json); phone/system-apps.json points there. The native crate's catalog and icons go. - The phone catalogs' native News/Maps/Photos rows, phone.yml's builds and tests of the three crates, phone/docs/{photos,maps}.md, and the README and ADR mentions (both languages). Cargo.lock updated by cargo metadata (four packages removed). Verified: cargo check --locked -p octosense; from phone/: cargo check --locked -p octosense-home --features mobile-apps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… process on macOS and Windows ADR 0004 §2 and §10 (#110). A linked native app the person has not switched is now hosted as its manifest entry declares for this target (native_apps.rs, `NativeApp::on_this_target`), replacing the hard-coded "robrix | finance | terminal are modules" rule (robrix and finance are not linked by any build): - Terminal: its own process on macOS and Windows; on Linux only with a Vulkan build (`MAKEPAD=vulkan`, new `makepad_vulkan` cfg in the shell's build.rs) in a Wayland session; in-process on phones. A crash in it no longer takes the shell down. - A declared process falls back to in-process where it has no process form (`apps::process_form`: its launcher row resolves neither to a checkout to `cargo run` from nor to a sibling binary). - App Hub, Rinx and AppCard are modules everywhere; Reference and Sheets keep their process default on the desktop. - `terminal: Module|Process` (and any `<id>: ...`) in wm/apps.splash and `--module <id>` still win. The process is found the way every catalog app is (clients.rs): out of a checkout, `cargo run --release --manifest-path .sources/makepad/Cargo.toml -p makepad-terminal --bin terminal --target-dir <home>/build/makepad`; otherwise the `terminal` binary beside `octosense`. Release packages do not ship that binary yet: that depends on OctoSense #94; until then a packaged build falls back to the in-process Terminal. The standalone terminal binary publishes `run` on the AI services bus. The bus now withholds it (ai_bus::WITHHELD_TOOLS, keyed by the app id the shell launched the client as): stripped from the registration and replay, and a call to it is dropped, so the assistant gets read_screen and read_scrollback only in either hosting. Behaviour changes: Terminal opens as a process on macOS/Windows; Rinx (default) and AppCard (opt-in) now open in-process without `--module` (they have no process form, so before they were not launchable on the desktop without the flag). Verified on macOS: cargo build --locked -p octosense; tools/check-shell-graph.sh -p octosense and -p octosense-home; cargo test --locked -p octosense-shell --features app-terminal: 348 passed; from phone/: cargo check --locked -p octosense-home --features mobile-apps, cargo test --locked --features mobile-apps -p octosense-shell: 358 passed; native_apps.py --check; tools unittests. Hidden desktop (MAKEPAD_HIDE_WINDOWS, MAKEPAD_REMOTE, scratch OCTOSENSE_HOME, MAKEPAD_WM_TEST_APP=terminal): "launched terminal as client 1" (a process, not "in-process"), cargo built the `terminal` bin into the scratch home, first frame drawn in the tile, zsh running under it, typed text reached it; /quit ended both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README layout tables (root, apps/, phone's `mobile-apps` row) still listed the native comparison modules (`apps/*/native`) that OctoSense-org#113 deleted; the script apps are the only versions. ADR 0004's Context "Today" row now says the crates were deleted by OctoSense-org#113 (not OctoSense-org#110, as a few pages had it). The desktop README drops the now-redundant `--module reference --module sheets` example. Docs only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Makepad main d653bc44 carries the end of the per-app Splash runtime gates under the ruling of 8 October 2026 (#450): #117 drops the URL, media, socket and instruction-budget gates, and #118 the capability check before a host.request (option (c), confirmed by the product owner). The storage jail, inert password fields and the runtime's own checks on location, saved lists, the camera preview and agent.notify stay; host services that need a grant check it themselves (the device service checks the app's grant and the person's device consent for every camera, microphone and location call). It also carries #110-#116: renderer, Android, Linux and TextFlow work. The runtime overlay is rebased onto the new base: 34 patches, tree 0e7e0dac. Resolved by hand: - Settings patch, Android IME: upstream defers HideTextIME (pending_ime_hide); ShowTextIME still skips a dismissed keyboard and publishes a new editor session, and now also cancels a pending hide; HideTextIME publishes the editor before deferring. - Settings patch, GL program cache: the validation state (NeedsValidation, Supported, Disabled, the probe of a fresh export) is applied to upstream's rewritten cache functions. - host-json-boundary and host-response-json: the capability pre-check they edited is gone. - host-response-json's raw-envelope test drops its refusal mode (the runtime no longer builds that envelope); host-api-runtime-fixes' nested callback test has the host refuse the location sample instead. makepad-map-script-api.patch is dropped: makepad#113 merged it. video-api-smoke no longer expects the runtime to refuse an unlisted URL. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Proposes ADR 0004 and adds dated amendment sections to ADR 0002, Home ADR 0002 and Home ADR 0004 that point to it (their text is not rewritten). Documentation only.
What ADR 0004 decides
system-apps.json. Native apps getnative-apps.jsonand a generator with--check, replacing the five hand edits a native app needs today. The native News, Maps and Photos crates are deleted.Verified facts it relies on (octos main
e6223ef)peer/preparestages 1–8 peers per call; the only overall limit is a soft cap of 8192.result.md,peer_gather).For octos (to raise on octos#2567)
As written, a turn the system agent starts on an app peer (
peer_send_input) is a kernel continuation, so it gets none of the app's tools or memory. ADR 0004 asks for originator-driven host turns, and has the shell relay those turns until then.Relation to open PRs
#106 (the
octoshost service for script apps) and #108 (toolbox tools for app agents) implement parts of it. #85 needs a rebase on #98. #101 (Rinx data outsideOCTOSENSE_HOME) is part of the storage move.Open
D1: may read-only questions call shareable read tools directly? Every change goes through the owning app's agent.
🤖 Generated with Claude Code