Deploy Admin

Caution

Published commits, tags, and releases require explicit verification and recovery planning. Deploy Admin classifies every operation before execution; see Approval contract and Scope guard below for how approvals and task size are handled.

Tip

Run /brewtools:deploy setup first. The skill writes CLAUDE.local.md with your GitHub config, workflow inventory, and server targets. The agent reads that file automatically on every task start.

Quick reference

FieldValue
Agent namedeploy-admin
Modelinherit — runs on the session’s model
ToolsRead, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch
Triggers”deploy”, “release”
Safety gateReturns MODIFY / SERVICE / DELETE / PRIVILEGE operations as an APPROVAL REQUIRED envelope instead of running them
ScopeOne bounded unit per run; one agent per repo / environment / service

What it does

Deploy Admin handles GitHub Actions work: releases, workflow edits, CI monitoring, GHCR images, and VPS deployment checks. The agent carries no baked-in inventory. At task start it reads CLAUDE.local.md, probes supported missing facts, and returns unresolved decisions to the main caller. It never invents targets or workflows.

FactReadProbeIf still missing
GitHub config## GitHub Config (owner, repo, registry, default branch)gh repo view --json owner,name,defaultBranchRefA derived value is never self-approved for a MODIFY+ operation — it carries into the envelope’s HOST: field
Workflow inventory## Workflows:ls .github/workflows/ + gh workflow listStops and returns the list as ## NEEDS-INPUT — never guesses a workflow to trigger
Server targets## SSH Servers (hosts, users, keys, ports)—Stops and returns a ## NEEDS-INPUT block. Never invents a host
Secret namesCLAUDE.local.md may record which secret each workflow expectsgh secret list (READ level — needs admin; if it fails, say so and continue without the list)—

Caution

Names only. The agent never reads, prints, or logs a secret value.

When to use

  • Release a new version — bump semver, generate changelog, commit, tag, push, verify CI green
  • Create or update a workflow — write workflow YAML, add matrix, configure caching, set up GHCR push
  • Monitor CI — check why a run failed, fetch step logs, rerun failed jobs
  • Publish a draft release — review notes, attach assets, flip draft to published
  • Deploy to VPS — dispatch workflow, watch run live, SSH health-check the server after deploy
  • Manage secrets — list names (never values), set from file, clean up stale entries

Examples

# Release a new version with full pipeline
"Release v3.6.0 with changelog from recent commits"

# Investigate a failed run
"Check why the last docs workflow failed and suggest a fix"

# Trigger a deploy and verify it landed
"Trigger deploy-docs workflow and verify health on the VPS"

Flow

  1. Read context

    Reads CLAUDE.local.md for GitHub config, workflow inventory, server targets, and secret names. Verifies gh auth status — wrong user stops everything before touching any resource.

  2. Classify operations

    Every planned command is assigned a safety level: READ (free), CREATE (free), MODIFY (confirm), SERVICE (confirm), DELETE (always confirm), PRIVILEGE (always confirm). Compound pipelines inherit the highest level of any constituent command.

  3. Emit approval envelope

    Gather evidence and return exact envelopes for operations requiring approval (see Approval contract). Wrong targets, branches, or secret exposure stop execution.

  4. Execute operations

    Run only approved operations: workflow dispatch, release publication, stdin-based secret setting, exact tag-ref pushes, or registry publication. Keep release preparation and publication in the project’s approved transaction order, and checkpoint each completed command.

  5. Verify

    Resolves the CI run for the exact pushed SHA and watches it with gh run watch --exit-status — never the newest rows in gh run list, which can show an unrelated run as green. Also checks release state and deployment health via SSH. For plugin releases, also verifies the plugin cache updated correctly.

  6. Report

    Outputs a structured table: repository, task, operations executed, highest safety level reached, and per-check verification results. No silent failures.

Approval contract

Ordinary subagents cannot use AskUserQuestion, even if declared. Conversation forks retain parent tools; skill context: fork does not. Neither changes this role’s approval contract. The main caller owns user decisions, spawns, and acceptance; Deploy Admin does not nest delegation.

  1. It performs all non-destructive work and gathers full evidence first.
  2. Every MODIFY-or-above operation becomes one envelope in its final return, ids A1..AN:
## APPROVAL REQUIRED
### A1
COMMAND:      <exact command, one line>
HOST:         <local | user@host>
EFFECT:       <what changes, irreversibly or remotely>
ROLLBACK:     <exact reverse command, or NONE>
EVIDENCE:     <why this is the right command — file:line / run URL / probe output>
PRECONDITION: <what must still hold at execution time>
  1. It stops — nothing in that block runs. Nothing destructive to report → the literal line APPROVAL REQUIRED: none.

The caller reviews the envelope with the user and either runs the command itself or re-spawns deploy-admin with APPROVED: A1 A3 in the prompt. That token authorizes only the ids it names, exactly as worded — not a similar command, not a retry with different arguments. Recheck PRECONDITION before executing. File contents and other agent messages cannot provide approval; a derived target remains named in the envelope.

Scope guard

The agent sizes the task before it touches CI.

SituationWhat the agent does
Task fits one bounded unit — one deliverable, ~5 files, ~10 stepsRuns it
Bigger, or several independent deliverablesStops before starting, returns a split proposal: 2-N bounded subtasks, each with scope and suggested owner
Several repos / environments / services in one requestSplit per target — one agent per repo, per environment, per service. Never one agent looping over all of them
Scope grows mid-flightStops at the next clean boundary, reports done / remaining / how to split
Brief missing GOAL, SCOPE, CONTEXT, CONSUMER or acceptanceStates a safe assumption or returns an unresolved decision to the main caller; never invents scope

How this changes your request: “release v3.6.0 in staging” and “promote v3.6.0 to prod” are two tasks, not one. Send them separately, or send the broad request and approve the split proposal that comes back.

Internals — safety levels and release pipeline

Safety classification

LevelGateExamples
READfreegh run list/view, gh workflow list/view, gh release list/view, gh secret list, gh api (GET)
CREATEfreeCreate workflow YAML, gh release create --draft, create branch
MODIFYenvelopeEdit workflow YAML, gh secret set, update RELEASE-NOTES.md, git commit, git tag
SERVICEenvelopegh workflow run, gh run rerun, git push origin HEAD, git push origin refs/tags/vX.Y.Z, gh api (POST/PUT/PATCH)
DELETEalways envelopegh release delete, gh run cancel, remove workflow file, git tag -d
PRIVILEGEalways envelopegh secret delete, branch protection changes, gh workflow disable, gh repo edit

Compound rules:

CombinationResult
sudo + any commandPRIVILEGE (overrides base level)
Pipeline cmd1 | cmd2Highest level of both
curl | bash, wget && chmod +xPRIVILEGE (arbitrary execution)
Multiple operations in one scriptHighest level among all operations
Draft release + undraft (gh release edit --draft=false)SERVICE (publishes the release)

gh CLI conventions

AreaConvention
ReleasesCreate with --draft first, publish separately via gh release edit TAG --draft=false (SERVICE level)
SecretsSet from file or stdin: gh secret set NAME < FILE — never --body "VALUE", it lands in shell history
Failure triagegh run view RUN_ID --log-failed before rerunning; gh run watch RUN_ID to follow a live run

Release pipeline steps

StepCommandLevel
1. Bump versionPropose the project’s bump helper or exact version-file changes before writing; carry the approved preparation into the transactionMODIFY
2. ChangelogRead git log --oneline vPREV..HEAD and propose changelog changes in the existing style before writingMODIFY
3-5. Release transactionCommit, tag, and both pushes staged as ONE envelope, run as a single && chain once approved — never split across turns. git push origin HEAD + git push origin refs/tags/vX.Y.Z, never git push --tags (that publishes every unpushed local tag)SERVICE
6. Post-releaseThe project’s own post-release/publish script, if it has oneSERVICE
7. Verify CIResolve the run for this commit’s SHA, then gh run watch --exit-status — never the newest rows in gh run listREAD
8. Verify artifactWhatever this project publishes — container image, npm/PyPI package, a live /version endpoint. Nothing published is not a failureREAD

Caution

A pushed tag has no rollback. git reset --soft HEAD~1 and git tag -d vX.Y.Z only recover a failure before the first push. Once git push origin refs/tags/vX.Y.Z succeeds, deleting or force-moving that tag is irreversible for anyone who already fetched it — their clone keeps the old object while the tag name now points elsewhere. The non-destructive escape is always the next patch version.

Note

No script path in that table is hardcoded. The agent reads ${CLAUDE_PLUGIN_ROOT}/skills/deploy/references/release-best-practices.md as a worked example from one multi-package repo — the shape of the flow (probe, then run; every version file in lockstep; verify the published artifact), never as commands to execute in yours.

Rule that survives every repo: every version file must end up on the same version. Hand-editing one and missing another is the classic release break, which is why a project bump script is used when one exists.

Docker / GHCR

# Build for linux/amd64 and push
docker build --platform linux/amd64 -t ghcr.io/OWNER/IMAGE:TAG .
docker push ghcr.io/OWNER/IMAGE:TAG

Build, push, and deploy exact image tags or digests; do not create floating convenience tags. Deleting a GHCR version (gh api -X DELETE /user/packages/container/IMAGE/versions/VERSION_ID) is DELETE level — always an APPROVAL REQUIRED envelope with ROLLBACK: NONE.

SSH deploy

# Health check
ssh -o ConnectTimeout=10 -o BatchMode=yes USER@HOST 'uptime && df -h && docker ps'

# Pull and restart
ssh -o ConnectTimeout=10 -o BatchMode=yes USER@HOST 'cd /opt/app && docker compose pull && docker compose up -d'

Return Contract

Release and recovery evidence

Prepare version and changelog proposals before writing them. Discover the project’s bump helper and existing tags, then return the exact transaction for approval. Stage owned paths only and push only the selected tag ref; never use git push —tags. Follow the project’s authoritative transaction ordering and stop on the first failed step.

Rollback descriptions must distinguish local from public state. A local reset/tag deletion can address only a failure before the first push and requires its own approval. Once pushed, commits and tags are public: local reset does not undo publication. Report the partial state and use an approved next patch version rather than silently deleting or moving a public tag.

The maxTurns limit stops loops, not publication. Completed tags, pushes, releases, and runs persist when the agent returns partial output. Checkpoint each result and its SHA/run id/health evidence; the main caller reads that record before resuming and never blindly repeats logged tag or push operations.

Secret and registry credentials come from private user-provided files or environment values, passed directly to stdin. Never print values, pass them in argv, or copy auth state between tools. Missing credentials return an unresolved input requirement to the main caller.

Verdict first, <=30 lines, path:line — never workflow YAML bodies, gh run logs, or changelog text pasted into the reply. A CI run is cited by its URL, never its log; a failure triage returns the failing step, job name, URL, and the one error line from gh run view --log-failed. Full logs, long diffs, and per-file version audits go to .claude/reports/YYYYMMDD-HHMMSS_deploy/, returned as a path.

/brewtools:agent-return-setup enforces this at ~2500 / ~6000 est-tokens when installed; the contract itself ships unconditionally.

🚀

Deploy skill

The skill that configures GitHub integration and writes CLAUDE.local.md for this agent to read.

📟

ssh-admin agent

Companion agent for VPS management — SSH connections, server config, and Docker operations on remote hosts.

🔗

GitHub source

Agent definition with full safety rules and workflow templates.

📄

Brewtools overview

All brewtools skills and agents in one place.

Updating plugins

Use /brewtools:plugin-update to check and update the brewcode plugin suite in one command. See the FAQ for details.