Skip to content

Host requests always settle, and the surface decides about sheets - #38

Merged
guofoo merged 2 commits into
mainfrom
feat/bounded-host-requests
Sep 30, 2026
Merged

guofoo merged 2 commits into
mainfrom
feat/bounded-host-requests

Conversation

@guofoo

@guofoo guofoo commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

On main, a host.request whose service never answers waits forever. The same happens when a service raises a sheet over a surface that cannot show one. For example, Mail's add_account never answers when it is called from a glance tile or an agent's tool call. This makes every request answer exactly once, and lets the surface, not the prompt capability, decide whether a service may raise a sheet.

Every request settles

  • Timeouts. A request times out after 60 s (DEFAULT_TIMEOUT); HostService::timeout lets a service ask for longer. The clock stops while the service's sheet is up for that request, because the person is typing. It restarts when the sheet closes, whether through close_sheet or close_sheet_later. A sheet that replaces another stops holding the earlier request.
  • One answer. An answer after the timeout, after cancel_heap(heap), or a second answer is dropped. The Card runner cancels the Card's and its sheet's requests when it closes, so nothing reaches a replacement.
  • Limits. 32 waiting requests per isolate and 256 in all. Arguments may be up to 1 MiB and answers up to 4 MiB. Malformed arguments or service names are refused instead of being read as null. Answers nobody takes expire after 2 minutes.
  • Sweeping. A small thread expires deadlines and wakes the UI. On wasm, the pump does this instead.

The surface decides about sheets

  • may_prompt on ServiceCall. It comes from makepad's per-isolate flag, which splash.rs documents as "true for a foreground app host, false for background surfaces like home-screen widget tiles". A sheet raised for a call without it is refused with an answer.
  • host_prompts is always true here. IsolateSettings::host_prompts no longer follows the prompt capability. The settings describe a foreground app, and a background host sets the flag false itself. Mail (["storage","mail"]) and AI providers (["storage","llm"]) do not request prompt, so tying the two would have refused their own sign-in and key sheets. prompt stays the app's own-questions capability.

The reply-queue type gets an alias, which also clears the clippy::type_complexity error appstore has on main.

Checks

  • cargo test --workspace: 182 passed. That includes 10 new services tests (timeouts, a late answer dropped, a longer service timeout, cancel on close, a background surface refused, a sheet holding its request, the per-isolate cap, malformed and oversized arguments, an oversized answer, stale answers expiring) and a new admission test (the surface, not prompt, decides).
  • Two tests were checked against mutations: with the refusal removed, the background test fails; with the sheet hold removed, the sheet test fails.
  • cargo clippy -p octosense-appstore -p octosense-app-policy --all-targets --no-deps -- -D warnings: clean.

Consumers

Every ServiceCall { … } literal needs may_prompt. The OctoSense side is OctoSense-org/OctoSense#204, a draft that pins this branch's head: glance tiles as a background surface, tool calls, Mail and AI providers refusing early, and the model service's longer timeout.

This branch includes App Hub main 0f33211 (runtime cb66de07). The merged tree was tested before it was pushed: 182 tests pass and clippy is clean.

Not in this PR: the "Where these are served today" paragraph in docs/PUBLISHING.md is out of date: OctoSense main registers model and octos. A generated capability matrix is proposed separately.

Every host.request now answers exactly once. On main a request whose
service never answers waits forever; a service's sheet raised over a
home-screen tile or for an agent's tool call is dropped, and Mail's
add_account never answers there.

- A request times out after 60 s (HostService::timeout lets a service
  ask for more). The clock stops while the service's sheet is up and
  restarts when it closes; a replaced sheet no longer holds its request.
- An answer after a timeout, after cancel_heap, or a second answer goes
  nowhere. The Card runner cancels the Card's and its sheet's requests
  when it closes, so nothing reaches a replacement.
- 32 waiting requests per isolate (256 in all), arguments up to 1 MiB,
  answers up to 4 MiB; malformed arguments are refused, not read as null.
  Answers nobody takes expire after 2 minutes.
- ServiceCall carries may_prompt, the isolate's surface permission from
  makepad. A sheet raised for a call without it is refused with an
  answer. IsolateSettings::host_prompts is true for a foreground app;
  it no longer follows the `prompt` capability, which Mail and AI
  providers do not request and which is about an app's own questions.
- The reply queue gets a type alias, which also clears the existing
  clippy::type_complexity error on appstore.
Follow App Hub main 0f33211 (runtime cb66de07, makepad 1f3b1ded, Octoscript dbd48cfb).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant