Files
scrabble-game/.claude/skills/deploy-check/SKILL.md
T
Ilia Denisov 7dabcd1317
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Has been skipped
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m23s
chore: track the deploy-check skill in the repo
The deploy-check skill is repo-specific: it encodes this project's hard-won
pre-deploy runtime constraints (distroless nonroot, edge Alt-Svc/HTTP3, caddy
recreate, DICT_VERSION boot, expand-contract migrations, the Telegram permission
model) and points at deploy/README.md, docs/ARCHITECTURE.md, docs/EDGE_HTTP3.md and
the agent memory files. It belongs with the deploy logic it guards, not in the global
config, so it travels with the repo and stays versioned alongside it.
2026-06-24 14:39:00 +02:00

5.0 KiB

name, description
name description
deploy-check Use before any deploy-touching change to this repo — phrases like '/deploy-check', 'is this prod-safe', 'before we deploy', 'deploy safety review', 'проверь перед деплоем', 'это безопасно для прода'. Runs a pre-deploy checklist of this project's hard-won runtime constraints against the current diff, so the crash classes that have bitten live environments get caught before shipping instead of after.

Pre-deploy runtime-constraint check

Triggered before shipping anything that touches the deploy contour (Dockerfiles, deploy/, Caddyfile, compose, migrations, boot guards, the Telegram side-service, edge config). The worst frictions in this repo were never logic bugs — they were environment mismatches that crashed a live env and forced a redesign. Run this list against the diff first; turn crash-and-redesign into a single pass.

This checklist is a prompt, not the source of truth. The canonical detail lives in deploy/README.md, docs/ARCHITECTURE.md, docs/EDGE_HTTP3.md, and the agent memory files referenced below — read them when an item is in play, and add a new class here when a new incident teaches one.

How to run it

  1. git diff <base>...HEAD --stat to see what the change actually touches.
  2. For every risk class below that the diff touches, perform the Check and report PASS / FAIL with the exact file:line to fix. Skip classes the diff does not touch — say which you skipped and why.
  3. Remember: deploy-job green ≠ healthy. CI's deploy probe has historically passed with a dead backend (it only checked static landing+gateway). Verify the real feature live (/readyz, the actual flow) after deploy, not just the green.

Risk classes

1. Container user — distroless nonroot UID 65532

  • Bit us: TLS keys chmod 600 for the host owner crash-looped gateway + bot at boot with "permission denied" — service images run UID 65532.
  • Check: any new/changed mounted secret, key, or config file must be readable by UID 65532 (0644, not 0600). Scan the diff for file modes, chmod, and new volume mounts. (memory: distroless-nonroot-mounted-secrets)

2. Caddy header pipeline ordering

  • Bit us: header_up delete after set nulled the value (the honeypot tag went empty); it passed CI and only showed up live.
  • Check: in any Caddyfile change, verify the set / delete / header_up ordering for every affected route, and test the tripwire/route on the live contour, not just CI.

3. Edge Alt-Svc / HTTP3

  • Bit us: edge advertised Alt-Svc: h3 while UDP/443 was never exposed (docker tcp-only + ufw tcp-only); clients cached it 30 days and stalled on dead QUIC before falling back to h2 — Mini App "hangs on load".
  • Check: any edge/caddy change keeps Alt-Svc: clear (or only advertises h3 if UDP/443 is genuinely exposed). (memory: tg-app-load-stall-dead-http3-altsvc, docs/EDGE_HTTP3.md)

4. Prod caddy config recreate

  • Bit us: prod rolling deploy did not recreate caddy on a config-only change (pinned caddy:2-alpine + admin off), so a new Caddyfile deployed GREEN but stayed inert until a manual docker restart.
  • Check: a config-only edge change must --force-recreate caddy in prod-deploy.sh roll(); never trust deploy-green for edge config. (memory: prod-deploy-caddy-config-recreate)

5. DICT_VERSION / dictionary boot

  • Bit us: an early DICT_VERSION refuse-boot guard was wrong and crashed the live env when bumped on a seeded volume; it had to be redesigned to "marker-wins".
  • Check: any change touching DICT_VERSION, dict load, or the boot guard must keep marker-wins semantics and survive a seeded volume and an image rollback. DICT_VERSION is a required build-arg (no default), single-sourced. A new dict goes live via the admin console upload, not a redeploy. (memory: dict-version-deploy-verify, contour-schema-change-wipe)

6. Migrations — expand-contract + rollback safety

  • Bit us / risk: a non-backward-compatible migration breaks image rollback (DB ahead of rolled-back code).
  • Check: migrations must be expand-contract (backward-compatible). A schema change adds the maintenance window + a consistent pg_dump in prod-deploy. On the test contour, a schema/wire-label change needs DROP SCHEMA backend CASCADE + backend restart (new code vs old persisted DB), else the contour breaks. (memory: contour-schema-change-wipe)

7. Telegram permission model

  • Bit us: permissions are an AND-intersection — default-allow with explicit denies, not default-deny; inverting it broke access.
  • Check: any change to the Telegram permission / relay logic preserves the AND-intersection default-allow shape. (memory: telegram-forum-relay-gotchas)

Output

A short PASS/FAIL table over the classes the diff touches, each FAIL with the exact file:line and the fix. If every touched class passes, say so plainly and name the post-deploy live check to run (not just "CI green").