---
name: fleet-operator
description: Fleet operations for Kell's Tailscale and Apple devices. Use when work targets lavender, deltaisland, indigo, or lilac; when an agent needs remote shell, deployment, service inventory, incident diagnosis, or fleet health; or when an iOS/iPadOS build must be installed, launched, tested, or inspected on a physical device.
---

# Fleet Operator

Treat the fleet as one control plane with explicit blast radius. Prefer live discovery over remembered state, Tailscale over public ingress, and evidence before mutation.

## 1. Orient

1. Identify the current host before choosing a remote path:

   ```sh
   hostname
   tailscale status --json 2>/dev/null || true
   ```

2. Read [references/devices.md](references/devices.md) for device identities and routes.
3. Run `scripts/fleet-snapshot.sh` when the request is fleet-wide, the target is unclear, or current availability matters.
4. State the current host, target, route, and requested authority.

Complete orientation only when all four are known. If already on the target, operate locally instead of SSHing back into it.

When a tailnet name or address changes, compare `Self.DNSName` and `Self.TailscaleIPs` with `tailscale serve status --json`, service units, scripts, and bound listeners. Record each Serve port and upstream before resetting stale entries. Rebuild only those entries, restart services that publish their own Serve rule, verify from another tailnet node, then update this skill's fleet references and install the repo version on the control node.

## 2. Choose the branch

- **Delta operations:** prefer `ssh dit` from Lavender. Use `ssh di` only when the tailnet route fails and public ingress is appropriate. Read [references/delta-services.md](references/delta-services.md) before changing a service. Use `/home/delta/apps` as the deployment root for services that run from a Git clone or a directory containing Docker or Docker Compose files.
- **Lavender operations:** work locally when possible. From another tailnet node, use OpenSSH as `kell` through MagicDNS or the Tailscale IP and rely on an existing key or interactive credential source.
- **Apple device operations:** use Lavender as the control plane. Tailscale supplies network reachability; Xcode pairing supplies device control. Read [references/mobile.md](references/mobile.md).

Complete branch selection when one target and one transport are selected and reachable.

## 3. Establish a baseline

Inspect only the relevant layer:

- Host: uptime, disk, memory pressure, failed units, and tailnet state.
- systemd: unit status, recent journal, listener, dependencies, and fragment path.
- Docker: Compose project, container state/health, recent logs, mounts, networks, and published ports.
- Deployment: repo/ref, working tree, configured deploy mechanism, current artifact, and health endpoint.
- Apple device: paired/available state, developer identity, destination, scheme, bundle identifier, and signing readiness.

Read configuration metadata without printing environment values, tokens, credentials, private keys, or full container inspections. Complete the baseline when the current state, failure boundary, and intended postcondition are observable.

## 4. Fly the change

Use a **flight plan** for every mutation:

1. Name the target device and the smallest service, app, or file set that can satisfy the request.
2. Capture rollback state: current ref/image, unit state, configuration backup location, or installed app version as applicable.
3. Execute the requested change through the owning mechanism: systemd, Docker Compose, the repo's deploy command, Xcode, or `devicectl`.
4. Verify the user-visible outcome, unit/container health, relevant logs, listener or endpoint, and rollback viability.
5. Report the target, route, commands or mechanism used, state changed, verification, and any remaining risk.

Normal read-only work is autonomous. A user-requested, reversible change to one service or app can proceed with the flight plan. Obtain explicit confirmation immediately before any reboot, firewall or tailnet-policy change, OS upgrade, account/key change, secret rotation, bulk service interruption, data deletion, or Docker volume removal.

## Credential handling

- Refer to the Delta key by path; never print, copy, or embed its contents.
- Use `sudo -n` only to test whether non-interactive elevation exists. If it does not, use an interactive prompt or stop for the user; never place a password in a command, environment variable, script, log, skill, or chat recap.
- Keep host authenticity checks enabled. Investigate a changed host key before proceeding.
- Prefer scoped SSH keys and existing credential stores over reusable passwords.

Complete the task only after the requested outcome is verified on the target or a concrete access blocker is reported with the next human action.
