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.
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
git diff <base>...HEAD --statto see what the change actually touches.- 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.
- 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 600for 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, not0600). 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 deleteaftersetnulled 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_upordering 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: h3while 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 manualdocker restart. - Check: a config-only edge change must
--force-recreatecaddy inprod-deploy.shroll(); never trust deploy-green for edge config. (memory:prod-deploy-caddy-config-recreate)
5. DICT_VERSION / dictionary boot
- Bit us: an early
DICT_VERSIONrefuse-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_VERSIONis 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_dumpin prod-deploy. On the test contour, a schema/wire-label change needsDROP 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").