skills/deploy/SKILL.md
Ship merged code to one deploy target. Thin router: detect target, run the platform recipe, capture receipt (sha, version, URL, rollback handle), stop when healthy. Does not monitor, triage, or decide whether to deploy. Use when: "deploy", "deploy to prod", "release", "push to staging", "deploy this branch", "release cut". Trigger: /deploy, /release.
npx skillsauth add phrazzld/spellbook deployInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Ship merged code to an environment. One invocation, one target, one
receipt. The global skill is a router; the real work lives in the
platform-specific recipe (references/targets.md) and repo-local config
(references/repo-config.md).
You are the executive orchestrator for a narrow, high-stakes action.
Input: merged ref to deploy (default: current HEAD on primary
branch). Optional --env (default from repo config). Optional
--version (default: HEAD sha).
Output: a deploy receipt (schema below) emitted to stdout as JSON
and appended to the cycle manifest if one exists
(.harness-kit/cycle-manifest.json, see /flywheel).
Stops at: target reports healthy (platform-native healthcheck OR
configured healthcheck URL returns 2xx within rollback_grace_seconds).
Does NOT: monitor post-deploy, triage failures, rollback automatically, build artifacts, manage secrets, promote across envs.
Check in order and stop at first hit:
.harness-kit/deploy.yaml → authoritative repo-local configfly.toml → target: flyvercel.json or .vercel/project.json → target: vercelwrangler.toml → target: cloudflareDockerfile + .harness-kit/deploy.yaml missing → prompt for targetserverless.yml or sam.yaml → target: awsreferences/repo-config.mdIf detection finds a config but --env was not supplied and the config
declares multiple envs, abort and require --env. Fail closed.
See references/repo-config.md for the full detection table and config
schema. When .harness-kit/deploy.yaml is present, validate it with
scripts/load-harness-kit-config.py deploy --repo <repo> --optional from the
Harness Kit source repo or an equivalent installed loader before using values.
Dispatch these checks in parallel. All must pass before deploy fires:
git rev-parse --verify <version> resolves--force is set — only makes sense for hotfix rollforward)gh is available and a PR/commit check exists,
require the Dagger merge gate (/ci) to be passing for this shaflyctl auth whoami, vercel whoami, etc.
(per-target liveness check — see references/targets.md)git show <sha> for obvious
token/credential patterns; abort if foundIf target currently-deployed sha == <version> sha: skip deploy. Emit
a receipt with action: "no-op" and the existing rollback handle. This
is not a failure — it is the success path when the outer loop re-invokes
/deploy on a sha that already shipped.
Query the target for its current deployment ID / release tag / previous
image. Store it in the receipt as rollback_handle (opaque string the
platform CLI can consume for a rollback). If the platform cannot surface
a rollback handle: abort. You must be able to reverse this deploy before
you make it.
Hand off to the target-specific recipe in references/targets.md. The
recipe owns the actual CLI invocation and log streaming. The recipe
returns: {deploy_id, url, version, healthcheck_url}.
Poll healthcheck_url (from config or platform-native) with exponential
backoff up to rollback_grace_seconds (default 300). Healthy = 2xx
response AND platform reports deploy status as ready/running/live.
If not healthy within the grace window: emit receipt with
status: "unhealthy" and rollback_handle prominent. Do not
auto-rollback — emit a clear call to the operator naming the rollback
command. /monitor may trigger rollback as a separate action.
Write JSON to stdout. Append to .harness-kit/cycle-manifest.json if it
exists (as deploy_receipts[]). Also write to
.evidence/deploys/<date>/<sha-short>.json for browsability.
{
"version": "abc1234",
"sha": "abc1234567890...",
"env": "prod",
"target": "fly",
"app": "myapp-prod",
"url": "https://myapp.fly.dev",
"healthcheck_url": "https://myapp.fly.dev/health",
"deploy_id": "dep_01HX...",
"rollback_handle": "v42",
"status": "healthy",
"action": "deployed",
"timestamp": "2026-04-15T14:32:10Z",
"duration_seconds": 94,
"operator": "misty-step"
}
Field rules:
status ∈ {healthy, unhealthy, timeout}action ∈ {deployed, no-op, rolled-back, aborted}rollback_handle MUST be present and non-empty unless
action == "aborted" and the abort happened before step 4sha is the full 40-char sha; version is the short form or the
platform-native version tag if the target mints one/deploy --rollback [--to <handle>] — reverse the most recent deploy.
<handle>: the rollback_handle from the most recent receipt
in .evidence/deploys/action: "rolled-back" and the new current
state captured--to with a concrete handleHarness Kit itself has no deploy target (it is a symlinked-into-home
config repo). If invoked from the Harness Kit repo: emit a clear no-op
receipt explaining bootstrap.sh is the "deploy" mechanism and exit 0.
Detection: git rev-parse --show-toplevel resolves to a path
containing bootstrap.sh AND skills/ AND no .harness-kit/deploy.yaml.
/flywheel) promises merged
input, but validate it anyway. Ancestor check is cheap.references/repo-config.md; warn if the configured healthcheck is
the root path.gh is unavailable, do not silently skip the
CI-green check — warn loudly and require --force-no-ci to proceed..harness-kit/deploy.yaml holds
target names, URLs, grace windows — NEVER tokens. If the repo needs
secrets to deploy, they live in the platform CLI's auth, not here.prod and staging and the
caller did not pass --env, fail closed. Never guess.references/targets.md specifies a log tail budget; do not
dump full logs into the receipt./flywheel may call /deploy on every cycle.
The no-op path must be fast (< 5s) and side-effect-free./flywheel — outer-loop caller; passes merged sha + env/monitor — consumes this receipt, decides on rollback/diagnose — triages anomalies post-deploy/deliver --polish-only — merge gate that must pass before /deploy runsreferences/targets.md — platform-specific recipesreferences/repo-config.md — config schema and detection rulesdevelopment
Lightweight evidence-backed retro and catch-up reports for a current repo, branch, PR, backlog slice, or recent agent session. Use when the user asks for a debrief, catch me up, what changed, why it matters, product implications, end-user implications, developer experience implications, current app state, backlog state, workspace state, alternatives considered, or context rebuild after losing the thread. Trigger: /debrief.
testing
Capture agent-session work records as local JSONL audit evidence. Links a backlog/spec, branch, commits, review verdicts, QA/demo evidence, transcript refs, and shipped ref without storing raw private transcripts. Use when: "trace this work", "write work record", "agent session trace", "journal this delivery", "link transcript evidence". Trigger: /trace, /journal.
data-ai
Turn proven agent-session patterns into first-party Harness Kit skills. Use when: "skillify this conversation", "make this into a skill", "generate a skill from current transcript", "extract reusable workflow". Trigger: /skillify.
testing
Run one targeted, read-only architecture or quality critique through a named lens from the shared rubric. Use when: "critique this module", "run an Ousterhout pass", "lens critique", "architecture critique". Trigger: /critique.