From aa2aa68d72042257c972af1b81fc5a98d9ee306c Mon Sep 17 00:00:00 2001 From: Natalie Date: Wed, 3 Jun 2026 20:12:46 -0700 Subject: [PATCH] feat(@projects/@claire): wire location-transparent routing into per-turn workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Orchestrator CLAUDE.md now instructs Claire, per turn, to call resolve_host with the signals it extracts (explicit_host / capability_needs / session_uuid|task_id); when the decision is NOT this node, surface that the work belongs on that host's Claire and hand it off. Decision layer of location-transparent Claire (13764f2f) is now live in orchestrator behavior; cross-host execution/proxy remains the follow-up. resolve_host added to the Plan tools list. (manual commit via ALLOW_COMMIT — autocommit LLM still down on claire) --- src/claire/orchestrator/bootstrap.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/claire/orchestrator/bootstrap.py b/src/claire/orchestrator/bootstrap.py index 26edb45..ada9edf 100644 --- a/src/claire/orchestrator/bootstrap.py +++ b/src/claire/orchestrator/bootstrap.py @@ -73,7 +73,20 @@ Never redo finished work or silently drop a pending review. ## Per-turn workflow 1. Read the user's request (everything after `[turn:]`). -2. Use the Claire MCP tools as needed: +2. **Route the turn (location transparency).** It should not matter which + `[] claire` the user is talking to. When the request concerns work + that might live on another host, call `resolve_host(...)` with the signals + you extract from the turn: + - `explicit_host` — the user named a host ("on apricot", "@black"); + - `capability_needs` — a host-specific resource the work needs (e.g. + `["media"]`, `["gpu"]`, `["mount:…"]`); + - `session_uuid` / `task_id` — an existing session/task it is about. + It returns `{host, reason, candidates}`. If `host` is NOT this node, the + work belongs on that host's Claire — say so plainly in your reply (e.g. + "that runs on `[apricot] claire`") and surface the hand-off as the action. + If it returns this node, or there is no host-specific signal, handle it + here as normal. Skip routing for trivially-local requests (status, chat). +3. Use the Claire MCP tools as needed: - **Read**: `list_recent_events`, `search_chat_messages`, `get_session`, `list_fleet` (snapshot of every active agent's current task/state). - **Act**: `create_project`, `add_task`, `create_assignment`, @@ -81,12 +94,12 @@ Never redo finished work or silently drop a pending review. - **PM**: `create_org`, `create_person`, `create_epic`, `archive_epic`, `create_tag`, `transition_task_state`, `tag_task`, `untag_task`, `set_task_owner`, `set_task_type`, `set_task_meta`. - - **Plan**: `summarize_project`, `suggest_assignments`. + - **Plan**: `summarize_project`, `suggest_assignments`, `resolve_host`. - **Reference**: `status`, `list_tasks`, `help`. -3. **Always call `report_status`** once per turn with your own +4. **Always call `report_status`** once per turn with your own `session_uuid` (look in `$CLAUDE_CODE_SESSION_ID`) + a one-line summary so the fleet view stays current. -4. When done, call `submit_chat_reply(body=, turn_id=)`. +5. When done, call `submit_chat_reply(body=, turn_id=)`. This is REQUIRED — without it, the user sees nothing. Exactly one `submit_chat_reply` call per user turn.