Skip to content

ai-host: the octos host service for contained apps (Card runner) - #106

Merged
ymote merged 3 commits into
mainfrom
feat/card-runner-octos
Sep 28, 2026
Merged

ymote merged 3 commits into
mainfrom
feat/card-runner-octos

Conversation

@ZhangHanDong

@ZhangHanDong ZhangHanDong commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Store and system apps the Card runner hosts that declare octos.* now reach the shell's assistant instead of no service answers "octos". The new octos host service (crates/ai-host/src/contained.rs) hands each app's calls to ONE host-owned peer, card.<app id>, owned by the system agent on the shell's kernel: the same app-peers contract Rinx uses, namespaced so a store app can never share a native module's peer or memory.

  • Arguments as Rinx: turn.start takes only text (non-blank, <= 32 KiB), the other three services take {}; unknown octos methods and sheet calls are refused.
  • One peer per app (created on first use, account device), one request context per app, reopened with a new generation when it closes.
  • Tool approvals are declined (the Card runner has no approval sheet yet) and listed in the reply's denied_approvals.
  • Replies over 2 MiB are refused.
  • Policy::contained_apps is the shell's switch: on in shipped(), off in none(); with it off the service answers that the assistant is off.
  • The logic runs without a kernel through a PeerFactory; the shell's factory (cfg(kernel)) launches peers with app_peers::hosted::launch. Tests use a fake factory over App Hub's real dispatch path.

Docs: docs/ai-services{,.zh-CN}.md and README{,.zh-CN}.md describe what a contained app can now use and hears, and how each answer was verified. The task contract is specs/card-runner-octos.spec.md.

Spec-Name: The octos host service for the Card runner
Spec-Passing: true
Spec-Summary: 14/14 passed, 0 failed, 0 skipped, 0 uncertain

Shipped default and follow-ups (ADR 0004)

Policy::contained_apps is off in Policy::shipped() until first-use consent exists. OCTOSENSE_CONTAINED_APPS=1 turns it on for development and tests.

Follow-ups:

  • First-use consent and a Settings off switch for each app agent (ADR 0004 section 4).
  • The agent workspace is the app's own account folder (section 11).
  • Approvals drawn by the shell instead of declined (section 8).
  • The tool set from the manifest plus the install-time grant (section 12), for example toolbox_peers::tools_for_manifest into hosted::launch_with_tools once toolbox-peers: offer the system toolbox to app agents (ADR 0002 §6, behind a feature) #108 lands.

Store and system apps the Card runner hosts that declare octos.* now
reach the shell's assistant instead of `no service answers "octos"`.
The new `octos` host service (crates/ai-host/src/contained.rs) hands
each app's calls to ONE host-owned peer, `card.<app id>`, owned by the
system agent on the shell's kernel: the same app-peers contract Rinx
uses, namespaced so a store app can never share a native module's peer
or memory.

- Arguments as Rinx: turn.start takes only `text` (non-blank, <= 32 KiB),
  the other three services take `{}`; unknown octos methods and sheet
  calls are refused.
- One peer per app (created on first use, account `device`), one request
  context per app, reopened with a new generation when it closes.
- Tool approvals are declined (the Card runner has no approval sheet
  yet) and listed in the reply's `denied_approvals`.
- Replies over 2 MiB are refused.
- Policy::contained_apps is the shell's switch: on in shipped(), off in
  none(); with it off the service answers that the assistant is off.
- The logic runs without a kernel through a PeerFactory; the shell's
  factory (cfg(kernel)) launches peers with app_peers::hosted::launch.
  Tests use a fake factory over App Hub's real dispatch path.

Docs: docs/ai-services{,.zh-CN}.md and README{,.zh-CN}.md describe what a
contained app can now use and hears, and how each answer was verified.
The task contract is specs/card-runner-octos.spec.md.

Spec-Name: The octos host service for the Card runner
Spec-Passing: true
Spec-Summary: 14/14 passed, 0 failed, 0 skipped, 0 uncertain

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ymote and others added 2 commits September 28, 2026 13:36
…rst-use consent

ADR 0004 section 4: an app's agent needs the person's consent the first
time the app asks. Until that exists, Policy::shipped() leaves the octos
service for contained apps off; OCTOSENSE_CONTAINED_APPS=1 turns it on for
development and tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ymote
ymote merged commit 8bcd39c into main Sep 28, 2026
4 of 5 checks passed
ymote added a commit that referenced this pull request Sep 29, 2026
… [skip ci]

- approvals/contacts.rs: ContactsSource (is_known for email addresses and
  Matrix IDs), ContactList/NoContacts test doubles, MailContacts reading
  Mail's host service data, and ContactsGate: off by default, on only by
  the person's Settings tap ("Use my contacts in approval rules"), kept
  owner-only in approvals/contacts.json. The router evaluates "recipients
  in contacts" through the gate.
- mail host service: contacts::known_addresses (own accounts, recorded
  send recipients, To/Cc of sent folders; never the secret store); the
  decoder keeps To/Cc; a removed account forgets its recipients.
- docs/ai-services(.zh-CN).md refreshed against main (#106, #113, #117,
  #118, #120, #124, #95, #86), linking architecture.md; architecture's
  contacts lines updated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
chrislearn pushed a commit to chrislearn/OctoSense that referenced this pull request Sep 29, 2026
Factual corrections checked against main baa90bd and octos acffad3b:
octos#2567 and OctoSense-org#106 are merged; the pin is acffad3b; generic_tools is an
exact list and omitting it keeps the whole roster (ask_user_question and
shell included), so octos's shell is kept out only by the _main
tool_policy (OctoSense-org#117); the peer link method is octos.session.open.
architecture.md and ai-services.md now reflect the system chat (OctoSense-org#132),
the peer link's shell side, the macOS sandbox and the Restart tile
(OctoSense-org#130), and the host-tool relay (OctoSense-org#145). ADRs 0002 and 0003 get dated
amendment notes for OctoSense-org#117. The system_tools.rs module doc no longer says
the command-execution switch does not exist.

Records two decisions of 2026-09-29 in ADR 0004: host.ask is dropped for
octos's ask_user_question routed by the shell (G11), and terminal.run is
process-only (G12).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

2 participants