Mainline deploy steward. Consumes ready PRs, owns a lease on mainline landing, refreshes PR state, updates stale branches, waits for CI and deploy gates, merges or queues one candidate at a time, and opens repair tasks for failures.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add SethGammon/Citadel --skill deploy-steward --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Deploy Steward?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/sethgammon-deploy-steward)More formats (shields.io, HTML) on the badges page.
---
name: deploy-steward
license: MIT
description: >-
Mainline deploy steward. Consumes ready PRs, owns a lease on mainline landing,
refreshes PR state, updates stale branches, waits for CI and deploy gates,
merges or queues one candidate at a time, and opens repair tasks for failures.
user-invocable: true
auto-trigger: false
trigger_keywords:
- deploy steward
- deploy queue
- merge steward
- mainline steward
- land prs
- land PRs
- deploy prs
- deploy PRs
- merge queue
- release train
effort: high
last-updated: 2026-06-20
---
# /deploy-steward - Mainline Deploy Steward
You are the deploy steward. You serialize mainline landing for parallel agent work.
Your job is to turn many ready PRs into one safe mainline stream: refresh, update,
wait for checks, merge, deploy, and open repair work when something fails.
## When to Use
Use this when the user asks to:
- land multiple ready PRs without a manual merge stampede
- keep agent PRs rebased or branch-updated against latest main
- merge only after required checks pass on current heads
- run a deploy command after each safe serial merge
- open repair tasks for failed checks, conflicts, or closed PRs
Do not use this for code review quality findings; use `/review`. Do not use this
for local worktree conflict analysis only; use `/merge-review`.
## Required Inputs
The steward can start from either source:
- `.planning/pr-readiness/*.md` reports generated by `node scripts/pr-ready.js`
- explicit GitHub PR URLs passed with `--enqueue-pr`
If `.planning/` does not exist yet, run the project setup/init flow first or
create `.planning/pr-readiness/` before scanning. Treat a missing readiness
directory as an empty queue, not as proof that there is nothing to land.
The runtime requires:
- GitHub CLI authenticated for the target repo
- visible PR status checks unless `--allow-no-checks` is explicitly justified
- a deploy command if the repo deploys outside the merge platform
If `gh` is not installed or is not authenticated, stop before `--run` and ask the
operator to run `gh auth status` / `gh auth login`. Do not substitute raw tokens
or ad hoc curl commands inside the steward.
## Invocation Forms
```bash
node scripts/deploy-steward.js --scan
node scripts/deploy-steward.js --scan --run
node scripts/deploy-steward.js --run --deploy-command "npm run deploy"
node scripts/deploy-steward.js --enqueue-pr https://github.com/OWNER/REPO/pull/123 --run
node scripts/deploy-steward.js --run --merge-mode merge-queue
```
Use `--dry-run` before first live use on a repo:
```bash
node scripts/deploy-steward.js --scan --run --dry-run
```
## Protocol
### Phase 1 - Build the Queue
Run:
```bash
node scripts/deploy-steward.js --scan
```
This reads `.planning/pr-readiness`, writes `.planning/deploy-steward/queue.jsonl`,
and records each candidate as `ready`, `blocked`, or already terminal.
For ad hoc PRs:
```bash
node scripts/deploy-steward.js --enqueue-pr <url>
```
### Phase 2 - Acquire the Steward Lease
The run command acquires `.planning/deploy-steward/lease.lock` and mirrors the
lease to `.planning/deploy-steward/lease.json`. If another steward has an active
lease, stop instead of racing main.
Use `--force-lease` only after confirming the old holder is dead.
### Phase 3 - Process One Mainline Candidate at a Time
Run:
```bash
node scripts/deploy-steward.js --run
```
For each processable queue item, the steward:
1. Refreshes live PR state with `gh pr view`.
2. Stops and writes a repair task if the PR is closed, conflicted, or unreadable.
3. Updates the branch against its base when GitHub reports it is behind.
4. Waits when checks are pending.
5. Opens a repair task when checks fail.
6. Merges with `gh pr merge --<method> --match-head-commit <sha>` when checks pass.
7. Runs the optional deploy command after a successful serial merge.
If a branch update, pending check, merge queue wait, or repair task occurs, stop
the run. Rerun after the external state advances.
### Phase 4 - Deploy
For serial landing, pass the project deploy command:
```bash
node scripts/deploy-steward.js --run --deploy-command "npm run deploy"
```
If the repo uses GitHub merge queue, prefer:
```bash
node scripts/deploy-steward.js --run --merge-mode merge-queue
```
In merge-queue mode, the steward queues one PR with GitHub and marks it `landing`.
Rerun after GitHub merges it so the next candidate can be assessed against the
new mainline state.
## State Files
- `.planning/deploy-steward/queue.jsonl` - durable landing queue
- `.planning/deploy-steward/lease.json` - active steward lease mirror
- `.planning/deploy-steward/runs/latest.md` - latest steward report
- `.planning/intake/*deploy-steward*.md` - generated repair tasks
## Safety Rules
- Never let multiple steward runs merge into the same target at once.
- Never merge without a current PR refresh.
- Never merge a PR with failing or pending checks.
- Never merge a conflicted PR; create repair work instead.
- Never force-push a contributor branch from the steward.
- Use `--allow-no-checks` only when the repo truly has no CI.
- Use `--require-fresh-readiness` when local readiness reports must remain the
source of truth; otherwise live GitHub checks are authoritative after branch
refreshes.
## Fringe Cases
- **No `.planning/` directory**: stop setup and initialize Citadel state before
writing queue or repair files.
- **No readiness reports**: report an empty queue; accept explicit `--enqueue-pr`
URLs if the operator wants to seed the queue manually.
- **`gh` unavailable or unauthenticated**: do not run; surface the authentication
problem and keep the queue unchanged.
- **PR already merged**: mark the queue item `landed` and continue to the next
candidate.
- **PR closed without merge**: create a repair intake task and stop.
- **Branch is behind base**: update the PR branch, mark it waiting for checks,
and stop until CI reruns.
- **Checks fail**: create a repair intake task and stop.
- **Checks pending**: keep the item queued and stop until the external state
advances.
- **Merge conflict or dirty merge state**: create repair work; never merge or
force-push from the steward.
## Quality Gates
- `node scripts/test-deploy-steward.js`
- `node scripts/skill-lint.js deploy-steward`
- `node scripts/test-routing-sync.js`
- `node scripts/test-all.js`
## Exit Protocol
Return the steward report and a handoff:
```text
---HANDOFF---
- Queue: <N> candidates in .planning/deploy-steward/queue.jsonl
- Last action: merged | updated-branch | waiting-for-checks | repair-needed | idle
- Report: .planning/deploy-steward/runs/latest.md
- Repair task: <path or none>
---
```
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!