sahin.io

All skills and agents

ship-to-production

Commit, push to main, wait for the Cloudflare deploy, and PROVE the change is live on sahin.io (deploy SHA + change marker + production screenshot). Use whenever the owner approves a change ("ship it", "deploy", "looks good", "amazing", "yes"), and as the last step of every finished change while auto-ship mode is on (see CLAUDE.md). Never report a change as done before this has confirmed it in production.

Source file
.claude/skills/ship-to-production/SKILL.md

Ship to production and prove it

Auto-ship mode is ON for this repo (CLAUDE.md). Once the owner has approved a change, do not ask "should I commit and push?" — run this whole loop and report the result. The owner should never have to ask whether something is deployed.

1. Gate (stop and report if any fail)

npx tsx scripts/gate.ts --full   # the deploy-gate skill: types, all tests, static build, SEO, bundles, worker

For UI changes the ui-before-after screenshots must already have been shown.

2. Commit only what belongs to this change

  • git fetch origin first; Manus and other sessions push to main. If HEAD..origin/main is non-empty, rebase onto it and re-run the gate.
  • Other Claude sessions work in this same checkout. git status will show files you did not touch: never git add -A. Stage your files by name. If the owner asked to ship everything, check the others pass the gate too and say whose work they are.
  • Never commit .claude/launch.json (local), dist/, .wrangler/.
  • Message: what changed and why, ending with the attribution line from the system reminder.

3. Push and confirm

git push origin main
npx tsx scripts/confirm-production.ts --expect "<path>::<marker>" [--expect ...]

confirm-production.ts waits for the "Deploy to Cloudflare Pages" run for HEAD, prints each job, polls until <meta name="x-deploy-sha"> on sahin.io equals HEAD, then checks each marker on the live page (HTML, or the JS bundles it loads for React changes). Pick markers unique to the change: a new class, id, heading, or string. It exits 1 with the reason on any failure.

The red "Create Cloudflare Pages project (if not exists)" annotation is expected (the project exists) and does not fail the run.

4. Look at production

npx tsx scripts/ui-compare.ts --production-only --out <scratchpad>/prod --path "<changed path>#<anchor>"

Read every PNG. This step is required, not optional: on 2026-10-08 it caught the new sidebar covering the home page's company list, which all checks had passed. If production looks wrong, fix it, and run this loop again.

5. Report

Send the production PNGs with SendUserFile, then reply with:

  • the commit SHA and subject, and the deploy run link
  • the confirm-production.ts result (deploy SHA live + markers found)
  • anything shipped that was not yours, or anything left uncommitted and why

If any step failed, say so plainly with the output. Never write "deployed" or "live" without a passing confirm-production.ts run.