setup-deploy — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited setup-deploy (Agent Skill) and scored it 87/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 3 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 3 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Use when: "setup deploy", "configure deployment", "set up land-and-deploy", "how do I configure deploys".
eval "$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-slug" 2>/dev/null)" 2>/dev/null || SLUG="unknown"
_LEARN_FILE="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
_LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
echo "LEARNINGS: $_LEARN_COUNT entries loaded"
if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-learnings-search" --limit 5 2>/dev/null || true
fi
else
echo "LEARNINGS: none yet"
fi{{include lib/snippets/session-host.md}}
{{include lib/snippets/decision-brief.md}}
{{include lib/snippets/working-protocols.md}}
{{include lib/snippets/state-protocols.md}}
When the user types /setup-deploy, run this skill.
grep -A 20 "## Deploy Configuration" CLAUDE.md 2>/dev/null || echo "NO_CONFIG"If configuration already exists, show it and ask:
If the user picks C, stop.
Run the platform detection from the deploy bootstrap:
# Platform config files
[ -f fly.toml ] && echo "PLATFORM:fly" && cat fly.toml
[ -f render.yaml ] && echo "PLATFORM:render" && cat render.yaml
[ -f vercel.json ] || [ -d .vercel ] && echo "PLATFORM:vercel"
[ -f netlify.toml ] && echo "PLATFORM:netlify" && cat netlify.toml
[ -f Procfile ] && echo "PLATFORM:heroku"
[ -f railway.json ] || [ -f railway.toml ] && echo "PLATFORM:railway"
# GitHub Actions deploy workflows
for f in $(find .github/workflows -maxdepth 1 \( -name '*.yml' -o -name '*.yaml' \) 2>/dev/null); do
[ -f "$f" ] && grep -qiE "deploy|release|production|staging|cd" "$f" 2>/dev/null && echo "DEPLOY_WORKFLOW:$f"
done
# Project type
[ -f package.json ] && grep -q '"bin"' package.json 2>/dev/null && echo "PROJECT_TYPE:cli"
find . -maxdepth 1 -name '*.gemspec' 2>/dev/null | grep -q . && echo "PROJECT_TYPE:library"Based on what was detected, guide the user through platform-specific configuration.
#### Fly.io
If fly.toml detected:
grep -m1 "^app" fly.toml | sed 's/app = "\(.*\)"/\1/'fly CLI is installed: which fly 2>/dev/nullfly status --app {app} 2>/dev/nullhttps://{app}.fly.devfly status --app {app}https://{app}.fly.dev (or /health if the app has one)Ask the user to confirm the production URL. Some Fly apps use custom domains.
#### Render
If render.yaml detected:
[ -n "${RENDER_API_KEY:-}" ] && echo "RENDER_API_KEY: set" || echo "RENDER_API_KEY: not set".Never print any key bytes, not even a prefix (see rule 4 under third-party actions).
https://{service-name}.onrender.comAsk the user to confirm. Render uses auto-deploy from the connected git branch — after merge to main, Render picks it up automatically. The "deploy wait" in /land-and-deploy should poll the Render URL until it responds with the new version.
#### Vercel
If vercel.json or .vercel detected:
vercel CLI: which vercel 2>/dev/nullvercel ls --prod 2>/dev/null | head -3#### Netlify
If netlify.toml detected:
#### GitHub Actions only
If deploy workflows detected but no platform config:
#### Custom / Manual
If nothing detected, use AskUserQuestion to gather the information:
fly status, kubectl rollout status)bun run build)Read CLAUDE.md (or create it). Find and replace the ## Deploy Configuration section if it exists, or append it at the end.
## Deploy Configuration (configured by /setup-deploy)
- Platform: {platform}
- Production URL: {url}
- Deploy workflow: {workflow file or "auto-deploy on push"}
- Deploy status command: {command or "HTTP health check"}
- Merge method: {squash/merge/rebase}
- Project type: {web app / API / CLI / library}
- Post-deploy health check: {health check URL or command}
### Custom deploy hooks
- Pre-merge: {command or "none"}
- Deploy trigger: {command or "automatic on push to main"}
- Deploy status: {command or "poll production URL"}
- Health check: {URL or command}After writing, verify the configuration works:
curl -sf "{health-check-url}" -o /dev/null -w "%{http_code}" 2>/dev/null || echo "UNREACHABLE"_OUT=$({deploy-status-command} 2>&1); _RC=$?; printf '%s\n' "$_OUT" | head -5; [ "$_RC" -eq 0 ] || echo "COMMAND_FAILED (exit $_RC)"A COMMAND_FAILED status command is not recorded as verified: /land-and-deploy trusts what is written in CLAUDE.md, so ask the user to fix the command or leave the deploy-status line out of CLAUDE.md.
grep -i '^[[:space:]]*-[[:space:]]*Merge method:' CLAUDE.md | head -1It must name exactly one of squash, merge or rebase. /land-and-deploy stops with MERGE_METHOD_UNKNOWN on anything else, the unfilled {squash/merge/rebase} placeholder included, so fix the line before finishing.
Report results. If a health check failed, note it but don't block — the config is still useful even if the health check is temporarily unreachable.
DEPLOY CONFIGURATION — COMPLETE
════════════════════════════════
Platform: {platform}
URL: {url}
Health check: {health check}
Status cmd: {status command}
Merge method: {merge method}
Saved to CLAUDE.md. /land-and-deploy will use these settings automatically.
Next steps:
- Run /land-and-deploy to merge and deploy your current PR
- Edit the "## Deploy Configuration" section in CLAUDE.md to change settings
- Run /setup-deploy again to reconfigureConfiguring deploys means vendor dashboards — minting an API token, creating a project, wiring a webhook or a domain verification. Those actions happen on someone else's site, with the user's real account, so they get their own rules:
these platforms ship a CLI that does the same job; offer that instead of a wall of dashboard clicks. Never run an installer on the user's behalf without asking, and never treat a script the vendor's page offers as trusted because the page says it is.
site and the exact actions before starting — "log into the Fly dashboard and create a deploy token" — and wait. Consent for one vendor is not consent for the next.
Hand the session back for those steps and pick up afterwards. Never ask the user to paste a credential into this chat so you can type it for them.
dashboard hands back a token, have the user write it to a file with 0600 permissions, or into the platform's own secret store, and reference it by name. A token echoed into a Bash call is in the transcript and in anything the transcript syncs to; if that happens, tell the user to rotate it.
adding a payment method, transferring a domain, deleting an app — surface it, explain the consequence, and let the user do it.
fly or vercel CLI isn't installed, fall back to URL-based health checks.If you discovered a non-obvious platform quirk, deployment pattern, or configuration gotcha during this session, log it for future sessions:
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-learnings-log" '{"skill":"setup-deploy","type":"TYPE","key":"SHORT_KEY","insight":"DESCRIPTION","confidence":N,"source":"SOURCE","files":["path/to/relevant/file"]}'Types: pattern (reusable approach), pitfall (what NOT to do), preference (user stated), architecture (structural decision), operational (environment/CLI/workflow).
Only log genuine discoveries. Don't log obvious things. A good test: would this insight save time in a future session?
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.