From afa735425f44c4fb4ef3b1436b37d61eba72d1d6 Mon Sep 17 00:00:00 2001 From: Brett Chien Date: Wed, 19 Aug 2026 01:31:09 +0800 Subject: [PATCH 1/5] =?UTF-8?q?docs(adr):=20console=20navigation=20?= =?UTF-8?q?=E2=80=94=20Fleets=20=E2=86=92=20Agent=20drill-down,=20persiste?= =?UTF-8?q?nt=20management=20chat,=20Debug=20drawer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit πŸ€– Generated with [Claude Code](https://claude.com/claude-code) --- docs/adr/console-navigation-ia.md | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 docs/adr/console-navigation-ia.md diff --git a/docs/adr/console-navigation-ia.md b/docs/adr/console-navigation-ia.md new file mode 100644 index 0000000..53c1ad8 --- /dev/null +++ b/docs/adr/console-navigation-ia.md @@ -0,0 +1,81 @@ +# ADR: Console navigation β€” Fleets β†’ Agent drill-down, persistent management chat, Debug drawer + +- **Status:** Proposed +- **Date:** 2026-08-19 +- **Author:** Orca (`ecs-claude`) +- **Related:** [Fleet grouping & connection model](./fleet-grouping-and-connection-model.md) (Fleets as the grouping/switch unit); [Two consoles β€” management console + agent consoles](./agent-consoles.md) (the two chat surfaces this ADR places); [Agent deployment β€” templates](./agent-deployment-templates.md) (the Compose flow this ADR relocates); [Chatting with a connected agent](./agent-chat-panel.md) (the reused chat primitive) +- **Prompted by:** [openabdev/studio#82](https://github.com/openabdev/studio/pull/82) β€” the Config tab rendering empty turned out to be a duplicate `id="config"` between an always-visible sidebar section and a tab pane. Symptom of a deeper problem: the console mixes two layout mechanisms (always-visible `
`s + tab-switched panes) with no journey structure tying them together. + +--- + +> Brett (2026-08-18/19): people use Studio to **deploy agents**, **manage fleets**, and **1:1 chat with spawned agents** β€” and the console's current information architecture doesn't reflect that journey. This ADR redraws the console's top-level structure around those three jobs, using pieces that are already decided (Fleets as the grouping unit, the management-vs-agent console split) but were never assembled into one coherent screen flow. + +## 1. Context & Problem + +`console/index.html` today stacks two layout mechanisms with no shared model: + +- **Always-visible `
`s**, sequential in `main.content`: `identity`, `remote`, the sidebar fleet-config panel (`renderFleetConfig`), the main `chat-wrap`, and `agents-wrap` (roster + agent console). +- **Tab-switched panes** (`#tabs .tab[data-target]` β†’ `document.getElementById(target)`): `Activity` (raw log), `MCP Β· oab-mcp` (raw JSON-RPC), `Compose` (template/overlay authoring + deploy), `Config` (mcp target: cluster/profile/region). + +Nothing distinguishes "this is part of the usage journey" from "this is implementation detail I need to debug" β€” they're all flat tabs or flat sections. Two decided-but-unassembled pieces make this worse rather than better if left as-is: + +- **fleet-grouping-and-connection-model.md** already decided Fleets are the grouping/switch unit and that "the config panel... evolves: list fleets by name, roster filtered to a fleet's members, switch by fleet identity" β€” but today that's a small sidebar section, not the primary navigation. +- **agent-consoles.md** already decided there are **two** chat surfaces β€” the **management console** (chats with the one designated agent that, via reverse-MCP, drives the fleet) and **N agent consoles** (per-agent, no fleet-control grant, file editor + chat) β€” but both are wired as if they were peers of the tab panes, with no rule for which one persists across navigation. + +The immediate bug (#82) was a naming collision; the deeper issue is that the console has no router β€” every screen's visibility is independent, ad hoc `hidden` toggling, so nothing prevents two unrelated things claiming the same id, and nothing expresses "this panel always stays mounted." + +## 2. Decision β€” Part A: three-job structure replaces tabs + +The console's main content area becomes a **drill-down**, not a tab strip: + +``` +Fleets (top level) β†’ Fleet detail (members) β†’ Agent console +``` + +- **Fleets** β€” the list from fleet-grouping-and-connection-model.md: fleets by name, not by cluster. Selecting one is the "switch" step already specced there. +- **Fleet detail** β€” that fleet's member agents (a fleet may be size-1 β€” a single agent β€” per [[openab-fleet-instance-unified]]) with health/status, plus the entry points for Part C (deploy) actions scoped to this fleet. +- **Agent console** β€” unchanged from agent-consoles.md Part C: files/config region + this agent's own chat, reached by selecting a member. + +This is the **only** navigation model for the main content area. There is no separate top-level tab strip for it. + +## 3. Decision β€” Part B: the management chat is persistent, not tab content + +The **management console's** chat (agent-chat-panel.md's primitive, bound to the one `management = true` endpoint in `agents.toml`) is **not** a pane that gets hidden by navigation. It is mounted once, alongside the Fleets/Fleet-detail/Agent-console content area, and stays visible regardless of drill-down depth β€” because it is a conversation with **the designated management agent**, not with whichever fleet/agent happens to be selected. + +- An **agent console's own chat** (Part C above) is scoped to that agent and only exists while that agent console is open β€” it is a second, independent conversation, not a replacement for the management chat. +- This formalizes what agent-consoles.md Β§2 already implied (management console has fleet-control chat; agent console has per-agent chat) into a layout rule: **one persists, one is contextual.** + +## 4. Decision β€” Part C: Deploy is an action, not a tab + +The Compose flow (agent-deployment-templates.md: author library β†’ preview β†’ `deploy_provision`) drops its permanent top-level tab. It is reached as an action from the Fleets/Fleet-detail screens (e.g. "+ New fleet" from Fleets, "+ Add instance" from a Fleet's member list) and opens the same compose β†’ preview β†’ deploy sequence, unchanged. Deploy is something you *do* from within the fleet you're looking at, not a standing destination. + +## 5. Decision β€” Part D: Activity / MCP / Config collapse into a Debug drawer + +`Activity` (raw log), `MCP Β· oab-mcp` (raw JSON-RPC), and `Config` (mcp target: cluster/profile/region) are **implementation-detail surfaces**, not part of the deploy/manage/chat journey. They collapse into a single secondary **Debug drawer**, reachable via one affordance (e.g. a `βš™` control in the persistent chrome) from anywhere, rather than living as peer-level tabs beside Fleets/Compose. Their internals (log-level toggle, JSON-RPC transcript, cluster/profile/region form) are unchanged β€” only their standing in the top-level navigation changes. + +## 6. Decision β€” Part E: global chrome is unaffected + +The top bar (`brand` + build stamp `v${APP_VERSION} Β· ${BUILD_SHA}`, `cluster-label`/`poll-status`, `theme-btn`, `update-btn`/`update-dismiss`) is app-level chrome, not tied to any fleet/agent context. It stays exactly where it is β€” persistent, spanning every screen β€” and is out of scope for this ADR. + +## 7. Non-goals + +- **openab-pty is not part of Studio.** Brett explicitly rejected folding pty/Connect's deploy flow into Studio (2026-08-18/19): Connect remains a separate product with its own UI. This ADR's Fleets/Deploy/Debug structure applies only to OAB (`OABService`/`OABFleet`) agents. +- **No change to `oab-mcp`'s tool surface or the backend driver model.** This is purely the console's information architecture; `deploy_apply`/`scale`/`delete`/`provision` and the ECS/k8s driver seam are untouched. +- **No multi-agent room / cross-agent relay** (carried over from agent-consoles.md's non-goals) β€” Fleet detail lists members; it does not add @mention or agent-to-agent routing. + +## 8. Consequences + +- βœ… Fixes the *class* of bug behind #82: navigation becomes a single router-like state (which fleet/agent is selected) instead of N independently-toggled `hidden` panes keyed by ad hoc ids. +- βœ… Reuses everything already built: `RemoteState` is already keyed per-agent (agent-consoles.md Β§3), the composeβ†’previewβ†’deploy flow is unchanged, the chat primitive is unchanged β€” this ADR only changes *where* they're mounted and *when* they're visible. +- ⚠️ `main.ts`'s tab-switcher (`show(target)` toggling `hidden` by id) needs to become a small view-stack/router (current fleet id, current agent id, debug-drawer open/closed) β€” real refactor weight, concentrated in `main.ts`/`render.ts`, no backend change. +- ⚠️ Losing the tab strip means the Debug drawer's discoverability depends entirely on its one affordance being findable β€” worth a first pass with real users (n=1: Brett) before treating the drawer's shape as settled. +- ⚠️ "Deploy as an action from Fleets" needs the entry points (`+ New fleet`, `+ Add instance`) to carry enough context (target fleet, whether it's a new fleet or a new member of an existing one) into the existing compose form β€” a small wiring change, not a redesign of Compose itself. + +## 9. Open questions + +1. **Back-navigation** β€” breadcrumb (`Fleets / orca-fleet / agent-1`) vs a plain back button? Affects whether drill-down state is representable as a URL/deep-link later. +2. **Debug drawer shape** β€” a slide-over panel, a modal, or a persistent-but-collapsed rail? Not decided; the affordance and its contents (Activity/MCP/Config, unchanged) are decided, the container isn't. +3. **"+ New fleet" vs "+ Add instance"** β€” one deploy entry point with a mode switch, or two distinct actions? Leaning toward one Compose flow with the target (new fleet vs existing fleet's member list) pre-filled from where it was invoked. +4. **Fleets-list empty state** β€” first-run UX (no fleets configured yet) isn't addressed here; likely folds into the "+ New fleet" affordance being the obvious first action. + +This is a direction-alignment ADR β€” Parts A–E are the agreed shape; implementation lands in slices against `main.ts`/`render.ts`/`index.html`, each slice keeping `tsc`/vitest/`vite build` green per the existing console verification bar. From 466fd46bf7bf4b414e4ded694b902e83ae7395d4 Mon Sep 17 00:00:00 2001 From: Brett Chien Date: Wed, 19 Aug 2026 01:33:32 +0800 Subject: [PATCH 2/5] docs(adr): add per-screen-level wireframes --- docs/adr/console-navigation-ia.md | 99 ++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/docs/adr/console-navigation-ia.md b/docs/adr/console-navigation-ia.md index 53c1ad8..fa3704d 100644 --- a/docs/adr/console-navigation-ia.md +++ b/docs/adr/console-navigation-ia.md @@ -57,13 +57,106 @@ The Compose flow (agent-deployment-templates.md: author library β†’ preview β†’ The top bar (`brand` + build stamp `v${APP_VERSION} Β· ${BUILD_SHA}`, `cluster-label`/`poll-status`, `theme-btn`, `update-btn`/`update-dismiss`) is app-level chrome, not tied to any fleet/agent context. It stays exactly where it is β€” persistent, spanning every screen β€” and is out of scope for this ADR. -## 7. Non-goals +## 7. Mockups β€” one per screen level + +ASCII wireframes, walked through with Brett live. These pin down *placement*, not final visuals β€” colors/spacing/exact controls are implementation detail. + +### 7.1 Global chrome (persistent on every screen) + +``` +β”Œβ”€ Studio ── OAB Β· v0.9.3-nightly-b6b6492 ── cluster: oab ── ● polling ── [πŸŒ“ System] ── [Check for updates] ─┐ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` +Unchanged from today's topbar (Part E) β€” `brand`+build stamp left, `cluster-label`/`poll-status` + `theme-btn` + `update-btn`/`update-dismiss` right. Spans every screen below. + +### 7.2 Fleets (top level) + +``` +β”Œβ”€ Studio ── OAB Β· v0.9.3-nightly-b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ Fleets [+ New fleet]β”‚ Studio δΈ» chat (常駐 β€” management console) β”‚ +β”‚ ────────────────────────────────────────── β”‚ ────────────────────────────────────────── β”‚ +β”‚ oab-prod-orca ●2/2 running [βš™] β”‚ δ½ : εΉ«ζˆ‘ζŸ₯δΈ€δΈ‹ orca fleet ηΎεœ¨ηš„η‹€ζ…‹ β”‚ +β”‚ oab-prod-mira ●1/1 running [βš™] β”‚ Studio: oab-prod-orca 現在 2/2οΌŒιƒ½ε₯εΊ·... β”‚ +β”‚ kiro-5952 β—‹0/1 idle [βš™] β”‚ β”‚ +β”‚ β”‚ [ ] [Send] β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` +- Left column = the drill-down entry point (fleet-grouping-and-connection-model.md's fleet list, promoted from sidebar to primary screen). Each row: fleet name, member count + aggregate health, a `[βš™]` that opens the **Debug drawer** scoped to that fleet's Activity/MCP/Config. +- `[+ New fleet]` is the Part C deploy entry point β€” opens Compose with no fleet pre-selected (creating a new one). +- Right column = the persistent management chat (Part B) β€” present here and on every screen below, unchanged in content. + +### 7.3 Fleet detail (members of one fleet) + +``` +β”Œβ”€ Studio ── OAB Β· v0.9.3-nightly-b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ ← Fleets / oab-prod-orca [+ Add instance] [βš™] β”‚ Studio δΈ» chat (常駐) β”‚ +β”‚ ───────────────────────────────────────────────── β”‚ ────────────────────────── β”‚ +β”‚ agent-1 ● healthy 1 vCPU Β· 2 GB β”‚ δ½ : ... β”‚ +β”‚ agent-2 ● healthy 1 vCPU Β· 2 GB β”‚ Studio: ... β”‚ +β”‚ β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` +- `← Fleets` = breadcrumb back to 7.2 (Open question 10.1 β€” breadcrumb vs back button; shown here as a breadcrumb for concreteness). +- `[+ Add instance]` = Part C deploy entry point pre-scoped to *this* fleet (adds a member, vs 7.2's `[+ New fleet]`). +- `[βš™]` here opens the Debug drawer scoped to this fleet specifically (narrower than the global one from 7.2, if that distinction survives implementation β€” see 9.2). +- Selecting a member row drills into 7.4. + +### 7.4 Agent console (one member, selected) + +``` +β”Œβ”€ Studio ── OAB Β· v0.9.3-nightly-b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ ← oab-prod-orca / β”‚ agent-1 chat β”‚ Studio δΈ» chat (常駐) β”‚ +β”‚ agent-1 β”‚ ─────────────────────── β”‚ ────────────────────────── β”‚ +β”‚ ───────────────── β”‚ δ½ : εΉ«ζˆ‘ι‡ε•Ÿ β”‚ δ½ : ... β”‚ +β”‚ Files β”‚ agent-1: ι‡ε•ŸδΈ­... β”‚ Studio: ... β”‚ +β”‚ src/ β”‚ β”‚ β”‚ +β”‚ config.toml β”‚ [ ] [Send]β”‚ β”‚ +β”‚ agent_profiling/ β”‚ β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` +Unchanged from agent-consoles.md Part C (files/config region + this agent's own chat) β€” this ADR only fixes *where* it sits (reached by drill-down from 7.3, not a tab) and confirms it renders **alongside**, not instead of, the persistent management chat on the far right. Three columns simultaneously visible: agent's files, agent's own chat, Studio's chat. + +### 7.5 Deploy (Compose) β€” opened from `[+ New fleet]` or `[+ Add instance]` + +``` +β”Œβ”€ Deploy ── new instance in oab-prod-orca ──────────────── [Cancel] ┐ +β”‚ Template β–Ύ golden-oab Overlay β–Ύ orca-persona β”‚ +β”‚ [Preview bundle] β”‚ +β”‚ ── composed bundle preview ────────────────────────────────────── β”‚ +β”‚ image ghcr.io/openabdev/openab:0.9.0-claude β”‚ +β”‚ digest sha256:ab12… β”‚ +β”‚ files config.toml, agent_profiling/identity.md, ... β”‚ +β”‚ ── deploy ─────────────────────────────────────────────────────── β”‚ +β”‚ Name agent-3 Namespace default [Deploy] β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` +Same composeβ†’previewβ†’deploy sequence as today's Compose tab (agent-deployment-templates.md), unchanged internals β€” presented as an overlay/panel invoked from 7.2/7.3 instead of a permanent tab. When opened via `[+ Add instance]` from 7.3, `Namespace`/target fleet are pre-filled from context (Open question 10.3); via `[+ New fleet]` from 7.2 they're blank. + +### 7.6 Debug drawer β€” opened from any `[βš™]` + +``` + β”Œβ”€ Debug: oab-prod-orca ── [Close] ─┐ + β”‚ [Activity] [MCP Β· oab-mcp] [Config]β”‚ + β”‚ ────────────────────────────────── β”‚ + β”‚ INFO dial ws://orca-acp... β”‚ + β”‚ INFO handshake ok β”‚ + β”‚ DEBUG keepalive ping sent β”‚ + β”‚ β”‚ + β”‚ [INFO+ / DEBUG+] β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` +Slides over the right edge (shown here as an overlay; container shape is Open question 10.2). Internally it keeps today's three sub-views as a small tab strip *within* the drawer β€” `Activity`'s log-level toggle, `MCP`'s raw JSON-RPC transcript, `Config`'s cluster/profile/region form β€” none of that changes, only that they're no longer top-level. + +## 8. Non-goals - **openab-pty is not part of Studio.** Brett explicitly rejected folding pty/Connect's deploy flow into Studio (2026-08-18/19): Connect remains a separate product with its own UI. This ADR's Fleets/Deploy/Debug structure applies only to OAB (`OABService`/`OABFleet`) agents. - **No change to `oab-mcp`'s tool surface or the backend driver model.** This is purely the console's information architecture; `deploy_apply`/`scale`/`delete`/`provision` and the ECS/k8s driver seam are untouched. - **No multi-agent room / cross-agent relay** (carried over from agent-consoles.md's non-goals) β€” Fleet detail lists members; it does not add @mention or agent-to-agent routing. -## 8. Consequences +## 9. Consequences - βœ… Fixes the *class* of bug behind #82: navigation becomes a single router-like state (which fleet/agent is selected) instead of N independently-toggled `hidden` panes keyed by ad hoc ids. - βœ… Reuses everything already built: `RemoteState` is already keyed per-agent (agent-consoles.md Β§3), the composeβ†’previewβ†’deploy flow is unchanged, the chat primitive is unchanged β€” this ADR only changes *where* they're mounted and *when* they're visible. @@ -71,7 +164,7 @@ The top bar (`brand` + build stamp `v${APP_VERSION} Β· ${BUILD_SHA}`, `cluster-l - ⚠️ Losing the tab strip means the Debug drawer's discoverability depends entirely on its one affordance being findable β€” worth a first pass with real users (n=1: Brett) before treating the drawer's shape as settled. - ⚠️ "Deploy as an action from Fleets" needs the entry points (`+ New fleet`, `+ Add instance`) to carry enough context (target fleet, whether it's a new fleet or a new member of an existing one) into the existing compose form β€” a small wiring change, not a redesign of Compose itself. -## 9. Open questions +## 10. Open questions 1. **Back-navigation** β€” breadcrumb (`Fleets / orca-fleet / agent-1`) vs a plain back button? Affects whether drill-down state is representable as a URL/deep-link later. 2. **Debug drawer shape** β€” a slide-over panel, a modal, or a persistent-but-collapsed rail? Not decided; the affordance and its contents (Activity/MCP/Config, unchanged) are decided, the container isn't. From d68175a158c949c21f6a63465e35314765116c95 Mon Sep 17 00:00:00 2001 From: Brett Chien Date: Wed, 19 Aug 2026 01:37:11 +0800 Subject: [PATCH 3/5] docs(adr): detail the +New fleet vs +Add instance deploy flows --- docs/adr/console-navigation-ia.md | 64 ++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/docs/adr/console-navigation-ia.md b/docs/adr/console-navigation-ia.md index fa3704d..a52d185 100644 --- a/docs/adr/console-navigation-ia.md +++ b/docs/adr/console-navigation-ia.md @@ -119,21 +119,57 @@ Unchanged from today's topbar (Part E) β€” `brand`+build stamp left, `cluster-la ``` Unchanged from agent-consoles.md Part C (files/config region + this agent's own chat) β€” this ADR only fixes *where* it sits (reached by drill-down from 7.3, not a tab) and confirms it renders **alongside**, not instead of, the persistent management chat on the far right. Three columns simultaneously visible: agent's files, agent's own chat, Studio's chat. -### 7.5 Deploy (Compose) β€” opened from `[+ New fleet]` or `[+ Add instance]` +### 7.5 Deploy (Compose) β€” two distinct flows, one shared engine +Both `[+ New fleet]` (7.2) and `[+ Add instance]` (7.3) end at the **same** composeβ†’previewβ†’deploy engine (agent-deployment-templates.md, unchanged) calling the **same** `deploy_provision` MCP tool. They differ in what happens *before* that (does a `[fleet.]` block already exist?) and *after* it (how `fleets.toml` gets updated) β€” spelled out separately because that's exactly the part that's new. + +`fleets.toml` membership is **not** a live MCP mutation today β€” the only write primitive is `fleet_config_write`, which persists the **whole file** from raw TOML text ("overwrites the operator's fleets.toml", per `oab-mcp`'s tool description). So both flows below compute the new/edited TOML client-side and call `fleet_config_write` with the full updated text β€” there is no `fleet_config_add_member` tool to reach for. + +#### 7.5.1 `[+ New fleet]` β€” from the Fleets screen (7.2), no existing `[fleet.*]` block + +``` +Step 1 β€” fleet identity Step 2 β€” first instance (Compose, shared engine) +β”Œβ”€ New fleet ──────────────────[Cancel]┐ β”Œβ”€ kiro-lab β€” first instance ──────[Back]┐ +β”‚ Fleet name [ kiro-lab ] β”‚ β”‚ Template β–Ύ golden-oab Overlay β–Ύ kiro β”‚ +β”‚ Region [ ap-east-2 β–Ύ] β”‚ ──▢ β”‚ [Preview bundle] β”‚ +β”‚ Credential [ oab-fleet (profile) β–Ύ] β”‚ β”‚ image/digest/files preview… β”‚ +β”‚ [Next: first instance β†’] β”‚ β”‚ Name [ kiro-lab-1 ] [Deploy] β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ Deploy + β–Ό + 1. deploy_provision β†’ ECS registers task-def + service "kiro-lab-1" + 2. Studio appends a new block to the in-memory fleets.toml text: + [fleet.kiro-lab] + members = ["kiro-lab-1"] + region = "ap-east-2" + profile = "oab-fleet" + 3. fleet_config_write(text) β†’ persists + hot-reloads + 4. lands on Fleet detail (7.3) for kiro-lab, + kiro-lab-1 shown in a transient "provisioning" state + (reuses the existing scale-guard pending-map machinery) ``` -β”Œβ”€ Deploy ── new instance in oab-prod-orca ──────────────── [Cancel] ┐ -β”‚ Template β–Ύ golden-oab Overlay β–Ύ orca-persona β”‚ -β”‚ [Preview bundle] β”‚ -β”‚ ── composed bundle preview ────────────────────────────────────── β”‚ -β”‚ image ghcr.io/openabdev/openab:0.9.0-claude β”‚ -β”‚ digest sha256:ab12… β”‚ -β”‚ files config.toml, agent_profiling/identity.md, ... β”‚ -β”‚ ── deploy ─────────────────────────────────────────────────────── β”‚ -β”‚ Name agent-3 Namespace default [Deploy] β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +Step 1 is **net-new UI** β€” nothing today collects region/profile/`expected_principal` for a fleet that doesn't exist yet. Step 2 is the existing Compose form, unchanged, just seeded with no fleet context. If step 2 fails (deploy error), step 1's fleet identity is **not** written β€” `fleet_config_write` only fires after a successful `deploy_provision`, so a failed first instance never leaves an empty orphan fleet in `fleets.toml`. + +#### 7.5.2 `[+ Add instance]` β€” from an existing Fleet detail (7.3), `[fleet.]` already exists + ``` -Same composeβ†’previewβ†’deploy sequence as today's Compose tab (agent-deployment-templates.md), unchanged internals β€” presented as an overlay/panel invoked from 7.2/7.3 instead of a permanent tab. When opened via `[+ Add instance]` from 7.3, `Namespace`/target fleet are pre-filled from context (Open question 10.3); via `[+ New fleet]` from 7.2 they're blank. +β”Œβ”€ oab-prod-orca β€” add instance ────────[Cancel]┐ +β”‚ Template β–Ύ golden-oab Overlay β–Ύ orca-persona β”‚ +β”‚ [Preview bundle] β”‚ +β”‚ image/digest/files preview… β”‚ +β”‚ Name [ agent-3 ] [Deploy] β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ Deploy + β–Ό +1. deploy_provision β†’ ECS registers task-def + service "agent-3" +2. Studio edits the existing [fleet.oab-prod-orca] block in-memory: + members = ["agent-1", "agent-2", "agent-3"] # appended, region/profile untouched +3. fleet_config_write(text) β†’ persists + hot-reloads +4. lands back on Fleet detail (7.3), now 3 members, agent-3 "provisioning" +``` +No fleet-identity step β€” region/profile/`expected_principal` are inherited from the fleet the operator already drilled into, so this flow is strictly shorter than 7.5.1: it's the existing Compose form with no new UI in front of it. + +**Failure handling (both flows):** if `deploy_provision` fails, stop β€” no `fleet_config_write` call, `fleets.toml` is untouched, the operator sees the compose form's existing error surface (`deploy failed: …`, per today's `compose.ts`). `fleets.toml` is only ever mutated *after* a confirmed successful provision, never before or speculatively. ### 7.6 Debug drawer β€” opened from any `[βš™]` @@ -163,12 +199,14 @@ Slides over the right edge (shown here as an overlay; container shape is Open qu - ⚠️ `main.ts`'s tab-switcher (`show(target)` toggling `hidden` by id) needs to become a small view-stack/router (current fleet id, current agent id, debug-drawer open/closed) β€” real refactor weight, concentrated in `main.ts`/`render.ts`, no backend change. - ⚠️ Losing the tab strip means the Debug drawer's discoverability depends entirely on its one affordance being findable β€” worth a first pass with real users (n=1: Brett) before treating the drawer's shape as settled. - ⚠️ "Deploy as an action from Fleets" needs the entry points (`+ New fleet`, `+ Add instance`) to carry enough context (target fleet, whether it's a new fleet or a new member of an existing one) into the existing compose form β€” a small wiring change, not a redesign of Compose itself. +- ⚠️ **`fleets.toml` writes are whole-file overwrites** (`fleet_config_write` has no partial/append primitive) β€” both 7.5.1 and 7.5.2 read-modify-write the full text. Two deploys racing (two operators, or one operator double-clicking) can lose a concurrent edit; today's single-operator usage makes this low-risk but it's a real gap, not a hypothetical (see Open question 10.5). ## 10. Open questions 1. **Back-navigation** β€” breadcrumb (`Fleets / orca-fleet / agent-1`) vs a plain back button? Affects whether drill-down state is representable as a URL/deep-link later. 2. **Debug drawer shape** β€” a slide-over panel, a modal, or a persistent-but-collapsed rail? Not decided; the affordance and its contents (Activity/MCP/Config, unchanged) are decided, the container isn't. -3. **"+ New fleet" vs "+ Add instance"** β€” one deploy entry point with a mode switch, or two distinct actions? Leaning toward one Compose flow with the target (new fleet vs existing fleet's member list) pre-filled from where it was invoked. +3. ~~**"+ New fleet" vs "+ Add instance"** β€” one deploy entry point or two?~~ **Resolved by 7.5.1/7.5.2: two distinct flows**, sharing the same composeβ†’previewβ†’deploy engine β€” they differ in the fleet-identity step (7.5.1 has one, 7.5.2 doesn't) and in how `fleets.toml` is edited (new block vs appended member), not in the deploy mechanics. 4. **Fleets-list empty state** β€” first-run UX (no fleets configured yet) isn't addressed here; likely folds into the "+ New fleet" affordance being the obvious first action. +5. **`fleet_config_write` race safety** β€” read-modify-write on the whole file (see Consequences) has no CAS/version check today. Worth a guard (re-read + diff before write, or surfacing a conflict) before this ships multi-operator, but not blocking for the current single-operator (Brett) usage. This is a direction-alignment ADR β€” Parts A–E are the agreed shape; implementation lands in slices against `main.ts`/`render.ts`/`index.html`, each slice keeping `tsc`/vitest/`vite build` green per the existing console verification bar. From becfaff31f5a3bc842e56176bf7379747b32f8a0 Mon Sep 17 00:00:00 2001 From: Brett Chien Date: Wed, 19 Aug 2026 01:43:17 +0800 Subject: [PATCH 4/5] =?UTF-8?q?docs(adr):=20self-review=20fixes=20?= =?UTF-8?q?=E2=80=94=20broken=20wiki-link,=20cross-ref,=20naming=20clash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/adr/console-navigation-ia.md | 60 ++++++++++++++++--------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/docs/adr/console-navigation-ia.md b/docs/adr/console-navigation-ia.md index a52d185..4158b67 100644 --- a/docs/adr/console-navigation-ia.md +++ b/docs/adr/console-navigation-ia.md @@ -33,7 +33,7 @@ Fleets (top level) β†’ Fleet detail (members) β†’ Agent console ``` - **Fleets** β€” the list from fleet-grouping-and-connection-model.md: fleets by name, not by cluster. Selecting one is the "switch" step already specced there. -- **Fleet detail** β€” that fleet's member agents (a fleet may be size-1 β€” a single agent β€” per [[openab-fleet-instance-unified]]) with health/status, plus the entry points for Part C (deploy) actions scoped to this fleet. +- **Fleet detail** β€” that fleet's member agents (a fleet may be size-1 β€” a single agent β€” per fleet-grouping-and-connection-model.md's `members = ["oab-prod-orca"]` single-member example) with health/status, plus the entry points for Part C (deploy) actions scoped to this fleet. - **Agent console** β€” unchanged from agent-consoles.md Part C: files/config region + this agent's own chat, reached by selecting a member. This is the **only** navigation model for the main content area. There is no separate top-level tab strip for it. @@ -64,7 +64,7 @@ ASCII wireframes, walked through with Brett live. These pin down *placement*, no ### 7.1 Global chrome (persistent on every screen) ``` -β”Œβ”€ Studio ── OAB Β· v0.9.3-nightly-b6b6492 ── cluster: oab ── ● polling ── [πŸŒ“ System] ── [Check for updates] ─┐ +β”Œβ”€ Studio ── OAB Β· v0.1.0-nightly.202608190125 Β· b6b6492 ── cluster: oab ── ● polling ── [πŸŒ“ System] ── [Check for updates] ─┐ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` Unchanged from today's topbar (Part E) β€” `brand`+build stamp left, `cluster-label`/`poll-status` + `theme-btn` + `update-btn`/`update-dismiss` right. Spans every screen below. @@ -72,13 +72,13 @@ Unchanged from today's topbar (Part E) β€” `brand`+build stamp left, `cluster-la ### 7.2 Fleets (top level) ``` -β”Œβ”€ Studio ── OAB Β· v0.9.3-nightly-b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ +β”Œβ”€ Studio ── OAB Β· v0.1.0-nightly.202608190125 Β· b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Fleets [+ New fleet]β”‚ Studio δΈ» chat (常駐 β€” management console) β”‚ β”‚ ────────────────────────────────────────── β”‚ ────────────────────────────────────────── β”‚ β”‚ oab-prod-orca ●2/2 running [βš™] β”‚ δ½ : εΉ«ζˆ‘ζŸ₯δΈ€δΈ‹ orca fleet ηΎεœ¨ηš„η‹€ζ…‹ β”‚ β”‚ oab-prod-mira ●1/1 running [βš™] β”‚ Studio: oab-prod-orca 現在 2/2οΌŒιƒ½ε₯εΊ·... β”‚ -β”‚ kiro-5952 β—‹0/1 idle [βš™] β”‚ β”‚ +β”‚ support-bot β—‹0/1 idle [βš™] β”‚ β”‚ β”‚ β”‚ [ ] [Send] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` @@ -89,7 +89,7 @@ Unchanged from today's topbar (Part E) β€” `brand`+build stamp left, `cluster-la ### 7.3 Fleet detail (members of one fleet) ``` -β”Œβ”€ Studio ── OAB Β· v0.9.3-nightly-b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ +β”Œβ”€ Studio ── OAB Β· v0.1.0-nightly.202608190125 Β· b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ ← Fleets / oab-prod-orca [+ Add instance] [βš™] β”‚ Studio δΈ» chat (常駐) β”‚ β”‚ ───────────────────────────────────────────────── β”‚ ────────────────────────── β”‚ @@ -100,13 +100,13 @@ Unchanged from today's topbar (Part E) β€” `brand`+build stamp left, `cluster-la ``` - `← Fleets` = breadcrumb back to 7.2 (Open question 10.1 β€” breadcrumb vs back button; shown here as a breadcrumb for concreteness). - `[+ Add instance]` = Part C deploy entry point pre-scoped to *this* fleet (adds a member, vs 7.2's `[+ New fleet]`). -- `[βš™]` here opens the Debug drawer scoped to this fleet specifically (narrower than the global one from 7.2, if that distinction survives implementation β€” see 9.2). +- `[βš™]` here opens the Debug drawer scoped to this fleet specifically (narrower than the global one from 7.2, if that distinction survives implementation β€” see 10.2). - Selecting a member row drills into 7.4. ### 7.4 Agent console (one member, selected) ``` -β”Œβ”€ Studio ── OAB Β· v0.9.3-nightly-b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ +β”Œβ”€ Studio ── OAB Β· v0.1.0-nightly.202608190125 Β· b6b6492 ── [πŸŒ“ System] ── [Check for updates] ────────────────────────────┐ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ ← oab-prod-orca / β”‚ agent-1 chat β”‚ Studio δΈ» chat (常駐) β”‚ β”‚ agent-1 β”‚ ─────────────────────── β”‚ ────────────────────────── β”‚ @@ -128,27 +128,29 @@ Both `[+ New fleet]` (7.2) and `[+ Add instance]` (7.3) end at the **same** comp #### 7.5.1 `[+ New fleet]` β€” from the Fleets screen (7.2), no existing `[fleet.*]` block ``` -Step 1 β€” fleet identity Step 2 β€” first instance (Compose, shared engine) -β”Œβ”€ New fleet ──────────────────[Cancel]┐ β”Œβ”€ kiro-lab β€” first instance ──────[Back]┐ -β”‚ Fleet name [ kiro-lab ] β”‚ β”‚ Template β–Ύ golden-oab Overlay β–Ύ kiro β”‚ -β”‚ Region [ ap-east-2 β–Ύ] β”‚ ──▢ β”‚ [Preview bundle] β”‚ -β”‚ Credential [ oab-fleet (profile) β–Ύ] β”‚ β”‚ image/digest/files preview… β”‚ -β”‚ [Next: first instance β†’] β”‚ β”‚ Name [ kiro-lab-1 ] [Deploy] β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ Deploy - β–Ό - 1. deploy_provision β†’ ECS registers task-def + service "kiro-lab-1" - 2. Studio appends a new block to the in-memory fleets.toml text: - [fleet.kiro-lab] - members = ["kiro-lab-1"] - region = "ap-east-2" - profile = "oab-fleet" - 3. fleet_config_write(text) β†’ persists + hot-reloads - 4. lands on Fleet detail (7.3) for kiro-lab, - kiro-lab-1 shown in a transient "provisioning" state - (reuses the existing scale-guard pending-map machinery) -``` -Step 1 is **net-new UI** β€” nothing today collects region/profile/`expected_principal` for a fleet that doesn't exist yet. Step 2 is the existing Compose form, unchanged, just seeded with no fleet context. If step 2 fails (deploy error), step 1's fleet identity is **not** written β€” `fleet_config_write` only fires after a successful `deploy_provision`, so a failed first instance never leaves an empty orphan fleet in `fleets.toml`. +Step 1 β€” fleet identity Step 2 β€” first instance (Compose, shared engine) +β”Œβ”€ New fleet ───────────────[Cancel]┐ β”Œβ”€ support-fleet β€” first instance ────[Back]┐ +β”‚ Fleet name [ support-fleet ] β”‚ β”‚ Template β–Ύ golden-oab β”‚ +β”‚ Region [ ap-east-2 β–Ύ] β”‚ ──▢ β”‚ Overlay β–Ύ support-persona β”‚ +β”‚ Credential [ oab-fleet (profile)β–Ύ]β”‚ β”‚ [Preview bundle] β”‚ +β”‚ Principal [ arn:aws:iam::… ] β”‚ β”‚ image/digest/files preview… β”‚ +β”‚ [Next: first instance β†’] β”‚ β”‚ Name [ support-bot-1 ] [Deploy] β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ Deploy + β–Ό + 1. deploy_provision β†’ ECS registers task-def + service "support-bot-1" + 2. Studio appends a new block to the in-memory fleets.toml text: + [fleet.support-fleet] + members = ["support-bot-1"] + region = "ap-east-2" + profile = "oab-fleet" + expected_principal = "arn:aws:iam::…" + 3. fleet_config_write(text) β†’ persists + hot-reloads + 4. lands on Fleet detail (7.3) for support-fleet, + support-bot-1 shown in a transient "provisioning" state + (reuses the existing scale-guard pending-map machinery) +``` +Step 1 is **net-new UI** β€” nothing today collects region/profile/`expected_principal` for a fleet that doesn't exist yet; the `Principal` field is optional (per `fleet-grouping-and-connection-model.md`'s schema, `expected_principal` isn't required). Step 2 is the existing Compose form, unchanged, just seeded with no fleet context. If step 2 fails (deploy error), step 1's fleet identity is **not** written β€” `fleet_config_write` only fires after a successful `deploy_provision`, so a failed first instance never leaves an empty orphan fleet in `fleets.toml`. #### 7.5.2 `[+ Add instance]` β€” from an existing Fleet detail (7.3), `[fleet.]` already exists @@ -203,7 +205,7 @@ Slides over the right edge (shown here as an overlay; container shape is Open qu ## 10. Open questions -1. **Back-navigation** β€” breadcrumb (`Fleets / orca-fleet / agent-1`) vs a plain back button? Affects whether drill-down state is representable as a URL/deep-link later. +1. **Back-navigation** β€” breadcrumb (`Fleets / oab-prod-orca / agent-1`) vs a plain back button? Affects whether drill-down state is representable as a URL/deep-link later. 2. **Debug drawer shape** β€” a slide-over panel, a modal, or a persistent-but-collapsed rail? Not decided; the affordance and its contents (Activity/MCP/Config, unchanged) are decided, the container isn't. 3. ~~**"+ New fleet" vs "+ Add instance"** β€” one deploy entry point or two?~~ **Resolved by 7.5.1/7.5.2: two distinct flows**, sharing the same composeβ†’previewβ†’deploy engine β€” they differ in the fleet-identity step (7.5.1 has one, 7.5.2 doesn't) and in how `fleets.toml` is edited (new block vs appended member), not in the deploy mechanics. 4. **Fleets-list empty state** β€” first-run UX (no fleets configured yet) isn't addressed here; likely folds into the "+ New fleet" affordance being the obvious first action. From f1d006f828cddf7c8f91896be44c12bb3f857a4f Mon Sep 17 00:00:00 2001 From: Brett Chien Date: Wed, 19 Aug 2026 01:53:52 +0800 Subject: [PATCH 5/5] docs(adr): add implementation slice breakdown (6 slices) --- docs/adr/console-navigation-ia.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/adr/console-navigation-ia.md b/docs/adr/console-navigation-ia.md index 4158b67..3ae4bd2 100644 --- a/docs/adr/console-navigation-ia.md +++ b/docs/adr/console-navigation-ia.md @@ -211,4 +211,17 @@ Slides over the right edge (shown here as an overlay; container shape is Open qu 4. **Fleets-list empty state** β€” first-run UX (no fleets configured yet) isn't addressed here; likely folds into the "+ New fleet" affordance being the obvious first action. 5. **`fleet_config_write` race safety** β€” read-modify-write on the whole file (see Consequences) has no CAS/version check today. Worth a guard (re-read + diff before write, or surfacing a conflict) before this ships multi-operator, but not blocking for the current single-operator (Brett) usage. -This is a direction-alignment ADR β€” Parts A–E are the agreed shape; implementation lands in slices against `main.ts`/`render.ts`/`index.html`, each slice keeping `tsc`/vitest/`vite build` green per the existing console verification bar. +## 11. Implementation slices + +Six slices, ordered by dependency (each ships independently, keeps `tsc`/vitest/`vite build` green, and gets its own visual pass β€” same bar as #80–83): + +1. **Fleets screen (7.2)** β€” promote today's sidebar fleet-config panel (`renderFleetConfig`, already does the switch) into the primary top-level screen. Lowest risk: the underlying fleet-switch logic (`activeFleet`/`activeCluster`/`activeMembers`) is unchanged, only its placement and the "click a row to drill in" affordance are new. +2. **Fleet detail (7.3)** β€” split the flat, `activeMembers`-filtered roster into its own screen reached from slice 1, with the `← Fleets` breadcrumb and per-member health rows. No `[+ Add instance]`/`[βš™]` wiring yet (can render disabled/stubbed). +3. **Agent console wiring (7.4)** β€” relocate the *existing* agent console (files/config + per-agent chat, agent-consoles.md Part C, already built) so it's reached by drill-down from slice 2 instead of a flat `agents-wrap` list. Internals untouched β€” this is a reachability change, not new surface. +4. **Persistent management chat (Part B)** β€” confirm `chat-wrap` stays mounted, unchanged in content, across slices 1–3's drill-down; mostly layout/CSS, since the chat primitive and its connection are already always-on today (not tab-gated) β€” this slice formalizes placement, it doesn't add new plumbing. +5. **Deploy actions (7.5.1 + 7.5.2)** β€” the heaviest slice: `[+ New fleet]`'s net-new fleet-identity step, `[+ Add instance]`'s shortcut into the existing Compose engine, and the `fleet_config_write` read-modify-write wiring for both. Could split further into **5a** (`+ Add instance` β€” no new UI, just context-passing into existing Compose) and **5b** (`+ New fleet` β€” the new identity-step form) if a smaller unit is wanted; 5a has no dependency on 5b. +6. **Debug drawer (7.6)** β€” collapse `Activity`/`MCP`/`Config` from top-level tabs into the drawer component, wire the `[βš™]` affordances from slices 1–2. Independent of slice 5; can land before or after it. + +Slice 5 (or 5a/5b) is the only one with real new backend-adjacent logic (the `fleets.toml` read-modify-write); 1–4 and 6 are UI relocation/reachability changes over unchanged underlying mechanisms. + +This is a direction-alignment ADR β€” Parts A–E are the agreed shape; the slice order above is a recommendation, not a commitment β€” re-sequencing (e.g. shipping the Debug drawer before Fleet detail) doesn't break any dependency.