Skip to content

ADR 0004: system chat in the shell, and the command-execution switch [skip ci] - #132

Merged
ymote merged 2 commits into
mainfrom
adr0004/system-chat
Sep 29, 2026
Merged

ymote merged 2 commits into
mainfrom
adr0004/system-chat

Conversation

@ymote

@ymote ymote commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Two ADR 0004 follow-ups: a chat with the system agent inside the shell, and the Settings switch for the system agent's command execution.

1. System chat (crates/shell/src/system_chat/)

  • Where you find it: Setup › Assistant › Assistant chat, or F8. On the desktop it opens as a column on the right. On a phone, or any window narrower than 720 pt, it fills the screen. --test-action system-chat and system-chat-send:<text> open it in hidden-window runs.
  • Which session: _main:api:octosense#system (the kernel's SYSTEM_SESSION). It connects over the shell's own kernel connection, octosense_ai_host::kernel::connect(). That is stdio, or the host-token WebSocket while Talk to Octos is on. It never starts a second kernel and never uses an external token. It connects when the pane opens and lets go when the pane closes, unless a turn is still running, so the kernel can still stop when idle.
  • What it shows:
    • streamed assistant text (message/delta, and v2 projection/envelope deltas and saved text)
    • tool calls with running, done or failed status (tool/started, tool/progress, tool/completed)
    • questions, answered with option buttons or free text (user_question/respond)
    • Stop (turn/interrupt) and New conversation (the kernel's /new, which does not call the model)
    • history from session/hydrate, falling back to session/messages_page
  • Kernel restarts: when the kernel restarts or crashes, the chat reconnects with back-off, reopens the same session and reloads its history. A turn that was running is reported as stopped.
  • Approvals: every approval/requested goes to the ADR 0004 §8/§4: approval router, standing rules, shell sheets, first-use consent #120 router as a system-agent call, with id syschat:<approval id>. Approvals from one turn go on one shell sheet, and the turn's prompt is the plan. The chat sends approval/respond only with the router's decision (approvals::take_system_chat_decisions). The pane only shows the approval's status.
  • No provider: the pane says "No model provider is set up yet" and offers Open AI providers. With no kernel, it says why.

2. Setup › Assistant › Command execution (system_chat/grants.rs)

  • Sits next to Approvals. Off by default. To turn it on, the person types the confirmation "let the assistant run commands" and then chooses Allow. This is the same pattern as Developer mode, turned on only by the person (ADR 0004 §13) #118's PersonGesture: only CommandGesture::settings_phrase makes the gesture, and a test checks that only lib.rs's Settings handler calls it. The row shows what turning it on risks. Turning it off never needs a gesture.
  • When on, SystemAgentTools::grant_command_execution(true) adds terminal.run to the system agent's host tools. It never adds octos's shell.
  • Each command goes through the router as ToolSpec::command() (auto_approvable: false), so no rule, not even "everything for 60 min", can approve it. A live sheet shows the exact command. Developer mode still approves it (§13).
  • When it applies: the kernel reads the grants when it starts. New system_tools::set_grants, grants_at_start and system_agent_tools_in_effect() in crates/kernel handle this. After a change the menu shows "Restart the assistant to apply" with a restart row (kernel::restart()), or "Applies when the assistant starts" if no kernel is running.
  • Saved in <home>/assistant/system-agent.json (0600).
  • Not yet possible: registering terminal.run on the system session needs octos#2567's per-session host tools. Until then the grant is recorded but the kernel does not offer the tool, and grants::request_command is the path each call will take.

Seams touched outside the new modules

  • crates/kernel: system_tools.rs (grant store and start snapshot), launch.rs (one call in prepare), lib.rs (system_agent_tools_in_effect). The README (en and zh-CN) now says command execution is done as a Settings grant, and that its host-tool registration waits on octos#2567.
  • crates/shell/build.rs: a kernel cfg, matching the one ai-host's build.rs sets.
  • crates/shell/src/approvals/mod.rs: routes syschat: decisions to the chat. approvals/tests.rs: the gesture scan allows system_chat/tests.rs.
  • crates/shell/src/lib.rs and shell/menu.rs: the widget, F8, pointer and keyboard routing, and the Setup › Assistant rows.
  • ai_host and app-peers: no edits. The existing octosense_ai_host::kernel re-export was enough.
  • ADR 0004 Follow-ups: both items ticked.

Tests

  • system_chat::tests, against a scripted kernel link: streaming assembly (legacy and v2), tool-call status, questions, interrupt, history load, new conversation, reconnect and resume after a restart, no provider and no kernel, closing the pane releases the connection, approvals answered only with the router's decision, batching into one sheet.
  • Command switch: needs the gesture and changes the tool set; saved owner-only; a command gets a live sheet that no rule can answer and developer mode can; a source scan shows only Settings makes a CommandGesture.
  • Kernel: a_start_takes_the_grants_of_that_moment.
  • Real kernel: a_system_agent_turn_from_the_pane_on_a_real_kernel runs with OCTOS_CORE_TEST_KERNEL and the scripted mock_llm.py. It drives the pane's driver through a turn, a kernel restart, resume, and a second turn. It passed locally with an octos 2.0.3-rc.13 build; without the variable it skips.
  • Menu: setup_assistant_offers_the_chat_and_the_command_switch.
  • Hidden-window desktop run (MAKEPAD_HIDE_WINDOWS=1 MAKEPAD_REMOTE, temporary home, no provider): the pane opened with the no-provider state and the Open AI providers button. F8 and typing filled the prompt. Setup › Assistant › Command execution showed the risk row and Allow; typing the phrase and choosing Allow saved the grant and showed "Command execution is on … Restart the assistant to apply". The runs ended with /gq. I checked the grabs.

Local checks run

cargo check for desktop (default and mobile-apps) and phone (mobile-apps); cargo test -p octosense-shell --lib for desktop (default and mobile-apps) and phone; cargo test -p octosense-kernel; tools/check-shell-graph.sh for both shells; tools/setup.py --check --cargo; tools/native_apps.py --check; rom/tests/test_no_local_paths.py.

Still to do

  • No dock icon. The chat is reached from the menu row and F8. Dock entries come from registered apps, and the chat is a shell surface, not an app.
  • The phone surface is the same pane drawn full screen, with text from the IME and the test action as its entry. It has not been run on a phone or emulator (unverified), and there is no home-page tile yet.
  • terminal.run registration and execution wait on octos#2567.
  • No real provider was configured; only the scripted model was used.

🤖 Generated with Claude Code

ymote and others added 2 commits September 28, 2026 18:56
…ystem_agent_tools_in_effect) [skip ci]

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…witch (ADR 0004 §6, §8, §12) [skip ci]

- crates/shell/src/system_chat/: a pane (Setup > Assistant > Assistant chat,
  F8; full screen on narrow screens and phones) on _main:api:octosense#system
  over the shell's own kernel connection: streamed text, tool calls with
  status, questions, interrupt, new conversation, history via session/hydrate,
  reconnect-and-resume after a kernel restart. Approvals go to the approval
  router batched per request (syschat: ids); the pane never approves.
- Setup > Assistant > Command execution: off by default, on only with the
  typed confirmation (CommandGesture), terminal.run joins the system agent's
  set from the next kernel start with a restart offered; each command is an
  auto_approvable:false router request; developer mode still answers it.
- Kernel README (en, zh-CN) and ADR 0004 follow-ups updated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ymote
ymote merged commit 1abee92 into main Sep 29, 2026
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.

1 participant