Skip to content

feat(cp): [fleet.<name>] schema with members — fleet grouping (ADR slice 1) - #34

Merged
brettchien merged 1 commit into
mainfrom
feat/fleet-named-schema-slice1
Aug 13, 2026
Merged

feat(cp): [fleet.<name>] schema with members — fleet grouping (ADR slice 1)#34
brettchien merged 1 commit into
mainfrom
feat/fleet-named-schema-slice1

Conversation

@brettchien

Copy link
Copy Markdown
Contributor

Drafted by Orca (ecs-claude) — flagging authorship (shared GitHub identity).

Backend slice 1 of fleet-as-usage-grouping (#33): a fleet is a named group with explicit members, decoupled from the physical cluster — two fleets may share a cluster (and one credential) while listing different members. This is what lets orca and mira be distinct fleets on cluster oab.

What:

  • studio-cp: FleetBinding gains members. FleetBindings deserializes from either the new [fleet.<name>] map form (name = key) or the legacy [[fleet]] array form — back-compat, so an existing fleets.toml keeps parsing unchanged — via an untagged intermediate. members empty ⇒ whole cluster (legacy semantics). Adds fleet_for_service + get(name); for_cluster unchanged (credential resolution stays cluster/account-granular for now).
  • oab-mcp: fleet_config reports members per fleet.

Back-compat matters: the operator's live laptop fleets.toml is the legacy [[fleet]] form — it must keep working, or Studio silently falls back to the ambient default and re-triggers the AccessDenied class of bug. Verified.

# new form — orca and mira as two fleets on one cluster
[fleet.orca]
cluster = "oab"
region  = "ap-east-2"
profile = "oab-fleet"
members = ["oab-prod-orca"]

[fleet.mira]
cluster = "oab"
region  = "ap-east-2"
profile = "oab-fleet"
members = ["oab-prod-mira"]

Verification: cargo check --tests -p studio-cp -p oab-mcp clean; the untagged+toml+from deserialize round-trip (legacy array, named map, empty) was verified in an isolated crate (the studio-cp test binary links the full aws-sdk, so its execution is left to CI's build-test).

Slice 2 (config panel: list by fleet, roster filtered to a fleet's members, switch by fleet identity) follows. Relates to #33.

🤖 Generated with Claude Code

…ce 1)

Backend for fleet-as-usage-grouping: a fleet is a named group with explicit
members, decoupled from the physical cluster — two fleets may share a cluster
(and one credential) while listing different members. Lets orca and mira be
distinct fleets on cluster `oab`.

- studio-cp: FleetBinding gains `members`; FleetBindings deserializes from the
  new `[fleet.<name>]` map form (name = key) OR the legacy `[[fleet]]` array
  form (back-compat — existing configs keep parsing unchanged), via an untagged
  intermediate. `members` empty ⇒ whole cluster (legacy semantics). Adds
  `fleet_for_service` and `get(name)`; `for_cluster` unchanged (credential
  resolution stays cluster/account-granular).
- oab-mcp: `fleet_config` now reports `members` per fleet.

Tests: legacy parse still matches by cluster (members empty); named fleets parse
with members + share a cluster; empty/comment-only parse to empty. Verified in
isolation that the untagged+toml deserialize round-trips both forms.

Slice 2 (config panel: list by fleet, roster filtered to members, switch by
fleet) follows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@brettchien
brettchien merged commit 846afec into main Aug 13, 2026
2 checks passed
@brettchien
brettchien deleted the feat/fleet-named-schema-slice1 branch August 13, 2026 17:48
brettchien added a commit that referenced this pull request Aug 14, 2026
…red to members (ADR Part A slice 2) (#35)

Backend slice 1 (#34) taught oab-mcp's fleet_config to report each fleet's
members. This wires the console (Part A slice 2 of the fleet-grouping ADR):

- **Switch by fleet identity, not cluster.** A fleet is a usage-based group,
  so two fleets can share a cluster (orca + mira on `oab`). The config panel's
  switch key moves from `data-cluster` to `data-fleet` (name); `FleetConfigEntry`
  gains `members`. Selecting a fleet derives the cluster it reads from and the
  member set it filters by.
- **Roster filtered to the fleet's members.** New pure `filterByMembers` keeps
  only deployments whose ECS service name (`oab-{ns}-{name}`) or short name is a
  member — mirroring studio-cp's `resolve_service`, which accepts both forms. An
  empty member list means whole cluster (legacy semantics), roster unfiltered.
- **List by fleet.** Each fleet button shows its member services as chips (or
  "whole cluster"); empty-config help now points at the new [fleet.<name>] form.
- Fixtures model the canonical shape: orca + mira sharing cluster `oab` with
  distinct members, and the new [fleet.<name>] TOML the editor loads.

Verification: tsc --noEmit + vite build clean; vitest 31/31 (9 new — member
filtering incl. short-name/full-name/empty cases, switch-by-name with a shared
cluster, member rendering). Console unit tests don't run in CI (only Rust does),
so this was run locally.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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