| name | pilotswarm-aks-deploy |
| description | Deploy PilotSwarm to AKS using the repo's canonical scripts and checks. Use when refreshing secrets, building/pushing the worker image, rolling out to AKS, or verifying provider/model changes in the live cluster. |
PilotSwarm AKS Deploy
Use this skill when the user wants to deploy PilotSwarm to AKS, refresh AKS env/secret state, or verify the live cluster after a rollout.
Keep the workflow repo-specific and explicit. Prefer the repo-owned scripts, and treat secret/env changes as part of the deploy surface, not as an afterthought.
This skill deploys pilotswarm only. Do not roll the same change into downstream projects or other clusters (for example waldemort or an app repo with a vendored PilotSwarm copy) unless the user explicitly asks for that separate deployment.
Canonical Targets
- Kubernetes context: resolve
K8S_CONTEXT from .env.remote
- Namespace: resolve
K8S_NAMESPACE from .env.remote
- Worker deployment:
copilot-runtime-worker
- Portal deployment:
pilotswarm-portal
- Worker image:
${ACR_NAME}.azurecr.io/copilot-runtime-worker:latest
- Portal image:
${ACR_NAME}.azurecr.io/pilotswarm-portal:latest
- ACR: resolve
ACR_NAME from .env.remote
- Azure subscription/resource ownership: prove from the active account, ingress IP, and ACR resource rather than assuming a resource group
- Portal DNS: resolve from live
pilotswarm-portal-ingress and verify against public DNS
- Postgres server: resolve the host from
.env.remote DATABASE_URL
- Location: derive from the proven AKS/public-IP resources
Do not hard-code ACR_NAME on the deploy command line โ scripts/deploy-aks.sh sources .env.remote after parsing the environment, so the .env.remote value wins. Set ACR_NAME in .env.remote if you need to override the default.
Set AZURE_SUBSCRIPTION_ID in .env.remote. The az CLI keeps its active subscription in ~/.azure โ global state shared by every terminal and editor window โ so deploying another environment (chk lives in a different subscription) from a second VS Code window silently repoints this one. The deploy scripts pass --subscription "$AZURE_SUBSCRIPTION_ID" to every az acr call when the variable is set, which turns that drift into a no-op instead of a confusing The resource with name '<acr>' โฆ could not be found in subscription 'โฆ'. Unset, the scripts fall back to ambient az state and the drift returns.
Subscription IDs are not recorded in this repo. Resolve the value the same way this skill resolves every other piece of topology โ from the live resources โ and put it in .env.remote, which is gitignored:
az account list --output table
az acr show --name "$ACR_NAME" --query id -o tsv
Canonical Files
Core Learnings
Default Deploy Workflow
-
Inspect the deploy surface.
- Run
git status --short.
- Review
.model_providers.example.json, the real .model_providers.json when the user has asked for local config changes, scripts/deploy-aks.sh, and deploy/k8s/worker-deployment.yaml if model/env/deploy behavior changed.
-
Verify the target env and cluster assumptions.
- Prefer
.env.remote for AKS deploys.
- Confirm the current context/namespace before changing remote state.
- Confirm the active Azure subscription before public-IP ownership, ACR, or deploy operations. A blank ownership result often indicates the wrong subscription, not an unowned IP.
- If the change removes a provider key, plan to verify the live model surface after rollout.
-
Use the canonical deploy script unless there is a concrete reason not to.
Deploys are always non-destructive: sessions, orchestrations, and facts
survive every deploy. There is no reset step or reset flag in a deploy.
-
If a manual deploy is needed, follow the same order as the script.
- Refresh the Kubernetes secret from the current env.
- Refresh the
acr-pull image-pull secret from ACR credentials/token.
- Run the local test gate unless explicitly skipped.
- Never fold a database reset into a manual deploy sequence โ a reset is a separate operation (see the NO RESETS rule).
- Build the SDK:
npm run build -w packages/sdk
- Login to ACR:
az acr login --name "$ACR_NAME"
- Build and push the image:
docker buildx build \
--platform linux/amd64 \
-f deploy/Dockerfile.worker \
--build-arg NPM_REGISTRY="${NPM_REGISTRY:-https://registry.npmjs.org/}" \
-t "$ACR_NAME.azurecr.io/copilot-runtime-worker:latest" \
--push .
- Apply namespace/deployment manifests and restart the deployment.
-
Verify the rollout.
- Check rollout status:
kubectl rollout status deployment/copilot-runtime-worker -n copilot-runtime --timeout=120s
- Check pod readiness:
kubectl get pods -n copilot-runtime -l app.kubernetes.io/component=worker
- Check recent logs:
kubectl logs -n copilot-runtime -l app.kubernetes.io/component=worker --prefix --tail=50
- If image correctness matters, inspect the running image IDs from the pods.
- Wait for old ReplicaSet pods to disappear before choosing a pod for file/catalog checks; rollout completion can overlap with terminating pods.
- If the rollout stalls in
ErrImagePull or ImagePullBackOff, inspect the pod events first; a stale acr-pull secret is a likely cause.
- Verify model-surface changes when env keys changed.
- If a provider key was added or removed, do not stop at "pods are Running".
- Verify the live selector surface in the TUI or through
list_available_models.
- Inspect the embedded runtime catalog too; compiled metadata support does not prove the image contains the intended catalog values.
- For Anthropic removal specifically, confirm Anthropic entries no longer appear after the restart.
- If the deploy followed a destructive reset, verify the rebuilt system baseline.
- Confirm the recreated
PilotSwarm Agent is present and not failed.
- Confirm the expected system children (
Sweeper Agent, Resource Manager Agent, Facts Manager) were respawned.
Secret Hygiene Rules
- Treat secret refresh as part of deployment, not a separate optional step.
- The deploy script already pushes:
DATABASE_URL
GITHUB_TOKEN when present
AZURE_STORAGE_* when present
AZURE_FW_GLM5_KEY
AZURE_KIMI_K25_KEY
AZURE_OAI_KEY
AZURE_GPT51_KEY
AZURE_MODEL_ROUTER_KEY
ANTHROPIC_API_KEY
- If a provider should disappear from selectors, make sure the corresponding env var is absent in the deploy env and then verify the restarted cluster reflects it.
Verification Fallbacks
- If
kubectl or kubelogin is flaky locally, use az aks command invoke for cluster-side verification instead of assuming rollout state.
- If local admin credentials are disabled, prefer the same cluster-side verification path rather than trying to force
--admin.
Extra Checks For Weird Behavior
Rules
- NO RESETS unless the user explicitly asks. Deploys never reset data. A database reset (
scripts/reset-db-aks.sh) is a separate, deliberate operation that requires the user to have literally asked for a wipe in the current conversation โ "deploy", "redeploy", "update the cluster", or an orchestration-version change is NOT such a request. When an orchestration change would benefit from a reset, say so and stop; do not run one.
- Never deploy without explicit user permission.
- Never skip the reset warning when orchestration behavior changed.
- Never assume a missing local env var means the live cluster already dropped that provider.
- Prefer repo scripts over handcrafted one-off deploy sequences.