Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
deploy-verify【部署与运维】Post-deploy smoke test across browser, Sentry, Supabase, Langfuse, and the public web. Use when "verify deploy", "smoke test production", "post-release check", or "ship or rollback". Deploy plus watch → workflow-ship-and-observe.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
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.
Observe: home loads; Sentry shows 12 new
TypeErroron/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-stallprotocol 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 10
Verify:
From the trace list, examine:
npx langfuse-cli api prompts list
Confirm 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 requests
If 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]
═══════════════════════════════════════════════════════