deploy-verify — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited deploy-verify (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
Degree of freedom: MIXED. Verdict and MONITOR escalation [HIGH freedom]; probe sequences and the report table [LOW freedom — run exactly].
Automated post-deploy health check across all services. Run after every deploy to catch regressions before users do. Works with any project — auto-detects configuration.
| Skill | Owns |
|---|---|
| deploy-verify (this) | Post-deploy smoke test across browser, Sentry, Supabase, Langfuse, public web |
workflow-ship-and-observe | Taking merged, green code to a verified, monitored production release |
workflow-launch-ready | Launch-preparation sweep before a new app or major release goes live |
Observe: home loads; Sentry shows 12 newTypeErroron/checkout; Supabase API 200s. Interpret: checkout is a critical path; errors started with this release. Classify: Sentry FAIL, smoke FAIL on checkout, DB PASS. Verdict: ROLLBACK — main money path is 5xx, not a MONITOR item.
deploy-npm; observe window → workflow-ship-and-observeRun within 15 minutes of deploy. The sooner you check, the smaller the blast radius.
Parallel where possible. Sentry, Supabase, and Langfuse checks are independent — issue them in one message (or one subagent each) so they run in parallel. Time matters here: do not spend time that can be avoided.
The verdict must be binary. SHIP, ROLLBACK, or MONITOR (with clear criteria for when MONITOR escalates to ROLLBACK).
Evidence over opinion. Every check produces a PASS/FAIL with specific data. Never say "looks fine."
Always use the `protocol-browser-anti-stall` protocol when using playwright-cli.
Grep(pattern: "vercel\\.json|netlify\\.toml|fly\\.toml|render\\.yaml|railway\\.json|Dockerfile|docker-compose|appspec\\.yml", output_mode: "files_with_matches")
Grep(pattern: "VERCEL_URL|RENDER_EXTERNAL_URL|FLY_APP_NAME|RAILWAY_STATIC_URL", glob: ".env*")Grep(pattern: "NEXT_PUBLIC_APP_URL|NEXT_PUBLIC_BASE_URL|VITE_APP_URL|PUBLIC_URL|PRODUCTION_URL|APP_URL", glob: ".env*")
Grep(pattern: "https://.*\\.vercel\\.app|https://.*\\.netlify\\.app|https://.*\\.fly\\.dev|https://.*\\.railway\\.app", glob: ".env*")Also check framework config files:
Grep(pattern: "url|domain|hostname", glob: "{vercel.json,netlify.toml,next.config.*}")Grep(pattern: "SENTRY_ORG|SENTRY_PROJECT|SENTRY_DSN|SENTRY_AUTH_TOKEN|@sentry/nextjs|@sentry/react|@sentry/node|sentry-cli", glob: "{.env*,package.json,.sentryclirc,sentry.*.config.*}")Grep(pattern: "SUPABASE_URL|NEXT_PUBLIC_SUPABASE_URL|SUPABASE_SERVICE_ROLE_KEY|SUPABASE_ANON_KEY", glob: ".env*")The project ref is the subdomain of the Supabase URL (https://<ref>.supabase.co). Confirm it with supabase:get_project_url.
The pack's Supabase MCP config is project-scoped (--project-ref), so its tools take no project_id and account tools such as list_projects are not registered. On a server started without a project ref, call supabase:list_projects to match the URL, then add "project_id": "<PROJECT_ID>" to each Supabase call below.
Grep(pattern: "LANGFUSE_PUBLIC_KEY|LANGFUSE_SECRET_KEY|LANGFUSE_HOST|@langfuse", glob: "{.env*,package.json}")Detect the app's route structure to identify critical paths for smoke testing:
Glob("**/app/**/page.{tsx,jsx,ts,js}")
Glob("**/pages/**/*.{tsx,jsx,ts,js}")
Glob("**/src/routes/**/*.{tsx,jsx,svelte}")Identify the critical paths (prioritized):
Record all detected values:
PRODUCTION_URLSENTRY_ORG, SENTRY_PROJECTSUPABASE_PROJECT_IDLANGFUSE_AVAILABLE (boolean)CRITICAL_PATHS (list of URLs to smoke test)sentry:find_organizations
{}Use the detected org slug and project slug from Phase 0c.
find_releases is a catalog tool, not a direct one, so call it through execute_sentry_tool. If the call is rejected, run search_sentry_tools with "find releases" to get the current name and schema.
sentry:execute_sentry_tool
{
"name": "find_releases",
"arguments": {
"organizationSlug": "<ORG_SLUG>",
"projectSlug": "<PROJECT_SLUG>"
}
}Verify:
sentry:search_issues
{
"organizationSlug": "<ORG_SLUG>",
"projectSlugOrId": "<PROJECT_SLUG>",
"query": "is:unresolved firstSeen:-1h",
"sort": "freq"
}Also check for regressions (previously resolved issues that re-opened):
sentry:search_issues
{
"organizationSlug": "<ORG_SLUG>",
"projectSlugOrId": "<PROJECT_SLUG>",
"query": "is:regressed",
"sort": "freq"
}For any new issue with high event count or critical severity, run Sentry's AI root-cause analysis:
sentry:analyze_issue_with_seer
{
"organizationSlug": "<ORG_SLUG>",
"issueId": "<ISSUE_ID>"
}This provides:
Decision criteria:
Skip this phase if no Supabase integration detected.
supabase:list_migrations
{}Verify:
Logs come from query_logs: read-only ClickHouse SQL over one logs table, filtered by source. Current Supabase MCP servers, local and hosted, list it instead of get_logs. Set iso_timestamp_start to 30 minutes ago; without it the window is the last 24 hours.
supabase:query_logs
{
"sql": "select timestamp, event_message, log_attributes['request.method'] as method, log_attributes['request.path'] as path, log_attributes['response.status_code'] as status_code from logs where source = 'edge_logs' order by timestamp desc limit 100",
"iso_timestamp_start": "<ISO_8601_30_MIN_AGO>"
}Check for:
supabase:query_logs
{
"sql": "select timestamp, event_message, log_attributes['response.status_code'] as status_code, log_attributes['function_id'] as function_id, log_attributes['execution_time_ms'] as execution_time_ms from logs where source = 'function_edge_logs' order by timestamp desc limit 100",
"iso_timestamp_start": "<ISO_8601_30_MIN_AGO>"
}Boot errors and exceptions print to the console stream, function_logs:
supabase:query_logs
{
"sql": "select timestamp, event_message, log_attributes['level'] as level, log_attributes['function_id'] as function_id from logs where source = 'function_logs' order by timestamp desc limit 100",
"iso_timestamp_start": "<ISO_8601_30_MIN_AGO>"
}Check for:
supabase:query_logs
{
"sql": "select timestamp, event_message, log_attributes['level'] as level, log_attributes['status'] as status, log_attributes['path'] as path, log_attributes['error'] as error from logs where source = 'auth_logs' order by timestamp desc limit 100",
"iso_timestamp_start": "<ISO_8601_30_MIN_AGO>"
}Check for:
supabase:get_advisors
{
"type": "security"
}supabase:get_advisors
{
"type": "performance"
}Flag any new warnings that weren't present before the deploy.
Run a quick data integrity check on the most important tables:
supabase:execute_sql
{
"query": "SELECT schemaname, relname, n_dead_tup, last_autovacuum FROM pg_stat_user_tables WHERE n_dead_tup > 10000 ORDER BY n_dead_tup DESC LIMIT 5"
}Decision criteria:
Skip this phase if no Langfuse integration detected.
npx langfuse-cli api traces list --limit 10Verify:
From the trace list, examine:
npx langfuse-cli api prompts listConfirm that active prompt versions match what the deploy should be using (check the production label).
Decision criteria:
PW="npx --yes @playwright/cli@latest"
$PW -s=deploy-verify open --headed "<PRODUCTION_URL>"Important: Apply the protocol-browser-anti-stall protocol:
sleep 2 → snapshot cycle (max 3)snapshot to detect ready stateFor each critical path identified in Phase 0f:
$PW -s=deploy-verify console$PW -s=deploy-verify requestsIf the app has auth:
Navigate to the primary feature and perform one basic interaction:
$PW -s=deploy-verify screenshot --filename ".playwright-mcp/deploy-verify-home.png"Decision criteria:
Aggregate all phase results into a final verdict.
| Scenario | Verdict |
|---|---|
| All phases PASS | SHIP — Deploy is healthy |
| All phases PASS except 1-2 MONITOR items | MONITOR — Watch for 1 hour, re-check |
| Any phase FAIL with a quick fix available | HOTFIX — Apply fix and re-verify |
| Any critical phase FAIL (auth broken, data loss, 5xx on main feature) | ROLLBACK — Revert immediately |
| Seer identifies a simple root cause for the only FAIL | HOTFIX — Apply Seer's fix, re-verify |
═══════════════════════════════════════════════════════
POST-DEPLOY VERIFICATION REPORT
Project: <PROJECT_NAME>
Deploy Time: <TIMESTAMP>
Production URL: <URL>
Checked At: <CHECK_TIMESTAMP>
═══════════════════════════════════════════════════════
## HEALTH CHECK RESULTS
| Check | Status | Details |
|------------------------------|---------|--------------------------------------|
| Sentry: new errors | ✅/❌ | [0 new / N new — list top issues] |
| Sentry: regressions | ✅/❌ | [0 regressed / N regressed] |
| Sentry: release tracked | ✅/❌ | [release ID and timestamp] |
| Supabase: migrations | ✅/❌ | [all applied / N pending/failed] |
| Supabase: API logs | ✅/❌ | [clean / N errors in last 30m] |
| Supabase: Edge Function logs | ✅/❌ | [clean / N errors] |
| Supabase: Auth logs | ✅/❌ | [clean / N errors] |
| Supabase: advisors | ✅/❌ | [no new warnings / N new warnings] |
| Langfuse: traces flowing | ✅/❌ | [N traces in last 15m / no traces] |
| Langfuse: latency | ✅/❌ | [normal / Xms above baseline] |
| Langfuse: prompt versions | ✅/❌ | [match expected / mismatch on N] |
| Smoke: home page | ✅/❌ | [loads in Xs / error] |
| Smoke: auth flow | ✅/❌ | [works / broken] |
| Smoke: main feature | ✅/❌ | [works / broken] |
| Smoke: console errors | ✅/❌ | [0 errors / N errors] |
| Smoke: network 5xx | ✅/❌ | [0 / N failed requests] |
## SEER ANALYSIS (if any P0 issues)
Issue: <ISSUE_ID>
Root Cause: <SEER_EXPLANATION>
Suggested Fix: <CODE_FIX>
Files Affected: <FILE_LIST>
## VERDICT
┌─────────────────────────────────────────────────┐
│ │
│ [SHIP / MONITOR / HOTFIX / ROLLBACK] │
│ │
│ Reason: <one-line explanation> │
│ │
│ Next action: <what to do now> │
│ │
└─────────────────────────────────────────────────┘
## MONITOR ESCALATION (if verdict is MONITOR)
Re-check in: [30 minutes / 1 hour]
Escalate to ROLLBACK if: [specific condition, e.g., error count exceeds 50]
Watch: [specific metrics to monitor]
═══════════════════════════════════════════════════════~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.