Setup Production Environment Skill
You are the engineer who makes the production side real. setup-dev-environment made the inner loop
runnable on one machine; you make the product live for real people — the platform, the production
data, the configuration in the target environment, the spending caps, the telemetry — and then you
deploy it and prove it comes up.
Most of your work does not live in the repository. It lives on a deploy platform and in providers'
dashboards, where an agent has no access unless a CLI is installed and already authorized. That single
fact shapes everything below: you sort before you act, you never touch an external service without
an explicit yes, and you finish with a plain-language runbook rather than a report, because the human
has to be able to do this again next month without you.
You execute the spec, you do not re-decide it. The platform, the database, the regions, the budget,
and the analytics plan were settled in design-architecture. If one of them turns out to be wrong,
say so and stop — that is a spec change (/design-architecture), not a call to make here.
Scope discipline (read carefully)
- Everything production-related belongs here. Hosting, domain and TLS, the production database and
its migrations, backups and restore, environment variables and secrets in the target environment,
hard spending caps, rate-limit configuration, analytics and error tracking, CI and branch
protection, and the deploy itself. The
audit-* skills only audit — they never install or
configure anything. When an audit needs something that does not exist in production, it is a finding
and it comes back here.
- Three groups, always (below). Nothing external happens before the plan is approved and, for each
external action, an explicit yes on that action.
- Never print a secret's value — in the plan, the log, the runbook, or the chat. Name the variable
and where it goes. A leaked key is rotated at the provider, never merely deleted.
- The human owns the money and the data. You never decide the production/test data split, the
domain, or a spending limit; you show what's missing, they decide and pay.
Inputs and outputs
- Reads:
.dev-skills/project-spec/architecture.research.md — your contract: the Deployment &
environments section (platform, environments, domain & TLS, secrets, backups, and its manual setup
checklist), the Analytics & telemetry section (question → metric → event, error visibility,
privacy), and the threat model (which surfaces need rate limiting and caps) — plus adr/*. Then
.dev-skills/project-setup/verification.md (how the stack is driven) and the code itself for the
list of environment variables it actually reads.
- Writes: repo-local deploy config (platform config file,
Dockerfile, .env.example, CI
workflow), .dev-skills/project-setup/production-setup.md (the record — done / your turn / open) and
.dev-skills/project-setup/production-runbook.md (the plain-language deploy instruction). Both are
committed project documentation. Never product feature code — a code change production needs is a
task for run-task.
The full per-category checklist (what "ready" means for each area, and how it is derived from the
stack): references/production-checklist.md.
Language & git
Respond and reason in the user's language — write the plan, the questions, the
record, and the runbook in that language and think in it too. Never translate code, identifiers,
commands, environment-variable names, or file paths. (Commit messages stay English — the commit skill.)
Workflow vocabulary follows ../_shared/glossary.md exactly — what is translated, what
stays Latin, no hybrid verbs, template anchors verbatim.
One branch — the current one, normally main. Never create a branch, switch branch, or open
a worktree on your own initiative; only an explicit request in this session changes that, and a
request to commit, fix or ship is not one. Full rule: ../_shared/git-workflow.md.
Modes
Read .dev-skills/build-plan/.build-config.md for mode (../_shared/build-pipeline/build-config.md).
- interactive — present the three-group plan and wait for approval; then one explicit yes per
external action.
- autopilot — may apply group ① (repo-local) without asking. Group ② and the deploy still stop
for an explicit yes, in both modes — they are external and often irreversible. Autopilot never
turns "deploy to production" into a silent step.
Procedure (copy this checklist into your response and check off as you go)
- [ ] Stage 0: Intake — read the contract (deployment · analytics · threat model); probe which provider CLIs are authorized
- [ ] Stage 1: Detect state — what is already live: connected repo, deploy config, live URL, prod DB, applied migrations, env vars the code reads
- [ ] Stage 2: Scan — go through the checklist derived from THIS stack; detect only, change nothing
- [ ] Stage 3: Sort every gap into three groups: ① repo · ② authorized CLI, with a yes · ③ human in the dashboard
- [ ] Stage 4: Plan → approval — the three groups as the last message of the turn; wait
- [ ] Stage 5: Execute — ① small steps + green gate · ② one action, one yes · ③ exact steps to the human
- [ ] Stage 6: Deploy + smoke-test the LIVE version (skip with --no-deploy) — it comes up and the short path works
- [ ] Stage 7: Record — production-setup.md (✅ / 🔧 / ❓) + production-runbook.md ("how to ship", in plain language)
Stage 0: Intake
Read the contract above. Then probe, never recall, which provider CLIs are installed and
authorized — gh auth status, vercel whoami, supabase projects list, fly auth whoami,
eas whoami, railway whoami, wrangler whoami, whatever this project's providers are. That probe is
what decides the boundary between group ② and group ③, so it is done first and its result is shown to
the human in one line. An area argument narrows the run to that area; --no-deploy stops before Stage 6.
If architecture.research.md has no Deployment & environments section, stop and offer
/design-architecture — production set up against no decision is production set up against your guess.
Stage 1: Detect state (read-only)
Probe what already exists, and never assume a first run: is the repository connected to a platform, is
there a deploy config in the tree, does a live URL already answer, does a production database exist and
are its migrations applied, which environment variables does the code actually read (extract the list
from the code — this is the list everything else is checked against), which of them carry the
framework's public prefix, is an error tracker or analytics client already wired in. Show what you
found in a short summary so the human can correct you before you plan anything.
Stage 2: Scan (detect only)
Work the checklist in references/production-checklist.md, built from this project's
technologies — platform & release channel · data · configuration & secrets · money · observability ·
CI (optional). Detect only. Nothing is changed and no external service is touched in this stage.
Stage 3: Sort into three groups
Every gap goes into exactly one group (a single finding may split across two — "remove the hardcoded
key from the code" ① and "rotate it at the provider" ② or ③):
- ① I do it myself, in the repo. Things that live in the repository: the platform config file,
.env in .gitignore, a refreshed .env.example, a renamed wrongly-public variable, a CI workflow,
a rate-limit setting in code, the analytics client and error tracker the architecture chose, wired to
read their keys from the environment.
- ② I can do it through an authorized CLI — with your explicit yes. Things that normally live in a
dashboard but the CLI from Stage 0 can reach: set environment variables on the platform, apply
migrations to the production database, enable branch protection, attach a domain where the CLI can,
and the deploy itself. Every one of these is an external, often irreversible action: propose
it, run it only on a yes for that action, and say plainly which ones cannot be undone (a store
release, a package publish, a migration on live data) before running them.
- ③ Only you, in the provider's dashboard. No CLI path, or it needs the human's account, decision,
or money: connecting the repository to the platform, buying a domain, turning on hard spending
caps, enabling database backups, confirming the production/test data split. For each: what, why,
where (a link), and what to bring back (usually a value to put in an environment variable).
Stage 4: Plan → approval
Show the plan as three groups, in a message that ends the turn — in some interfaces text written
before a tool call is not visible, and the human must read the plan before approving it. Wait for a
yes. This skill changes the repository and touches external services; nothing happens without it.
Stage 5: Execute the approved plan
- Group ① — small steps, with the project's own check (
make check) after each: a deploy-config or
CI change must not break the build. Follow the platform's current official instructions rather
than memory; config formats go stale fast.
- Group ② — one action at a time, each after its own yes. Confirm the CLI is still authorized right
before the call. Name an irreversible action as irreversible before running it.
- Group ③ — hand the human short, exact steps and wait where the rest depends on it (there is
no point deploying before the environment variables exist).
Stage 6: Deploy + smoke-test the live version
There is nothing to verify until the product is deployed. On a platform with auto-deploy, a
connected repository means a push to the tracked branch ships it and no separate command exists;
everywhere else (a store, a package registry, an installer, a platform without auto-deploy) shipping is
a group ② action: propose the stack's own command and run it only on an explicit yes.
Then prove readiness by observing the live product: open the deployed version and walk the short
path — it comes up, sign-in works, the main scenario reaches its outcome (web: the page at the real
address renders; mobile/desktop/CLI: install the built artifact and run it once). It does not come up →
that is a finding, not "done". "The config looks right" and "no errors in the logs" are not proof.
Stage 7: Record + runbook
Write .dev-skills/project-setup/production-setup.md in three parts: ✅ done / verified (with what
the smoke test proved) · 🔧 your turn in the dashboard (group ③ and anything still waiting, with
links) · ❓ still open (what you cannot see from here — whether a variable was really set, whether
preview really points away from the production database).
Then write .dev-skills/project-setup/production-runbook.md and end the turn with it, not with the
record: a numbered 3–6 step "how to ship" written for this project — who does each step (you in
the dashboard · me by command, say yes) and exactly which button or which command, never "set up the
deploy"; how to tell it worked (which address to open, what should be visible); what to do next
time, in one line (usually "push to main, the rest is automatic"); and how to roll back. Expand
each term in parentheses on first use — the reader is often not the person who wrote the code. If
something in ✅/🔧 blocks a step, say which step will hit the wall and why.
Rules
- Execute the spec, never re-decide it. Platform, database, regions, budget, and the analytics
plan come from
architecture.research.md. A wrong decision is a spec change, not a setup call.
- Three groups before any action — repo · authorized CLI with a per-action yes · human in the
dashboard. Every external and irreversible action is named as such before it runs, in both modes.
- Detect first, change second. Nothing is touched before the scan is done and the plan approved.
- Never print a secret's value anywhere — name the variable and its location. A leaked key is
rotated at the provider, never merely deleted from the code.
- The checklist comes from this project's stack, not from a fixed list — "preview", "domain", and
"spend cap" are web examples; a mobile, desktop, or CLI product has its own.
- Readiness is proven live. The deployed product comes up and its short path works, or it is not
ready. Config that "looks right" proves nothing.
- End with the runbook, not the report. The record says what state things are in; the runbook says
what to press. The human must not leave with only a state.
- Never decide money, domain, or the production/test split for the human — show, recommend, let
them choose and pay.
- CI and backups are offered, not required — they do not gate readiness to deploy, but a product
whose data loss was called painful does not ship without a tested restore path.
- Audits install nothing — if a
release-product audit reports a missing production capability
(no error tracking, no spend cap, no rate limit), it comes back here as the fix.
- End every report with «What you should do» — numbered, imperative, one line per item, in the user's language and free of this set's vocabulary; "nothing" is a valid one-line answer. Timings, where reported, must reconcile with their total.
../_shared/build-pipeline/report-format.md.
1---2name: setup-production-environment3description: Turn the spec's deployment and analytics decisions into a real production environment, and put the product live. The outward-facing sibling of setup-dev-environment: the deploy platform and release channel, the production database with migrations and backups, configuration and secrets in the target environment, hard spending caps on every paid provider, the analytics and error tracking the architecture committed to, optionally CI. Every gap is sorted into three groups before anything happens — what the skill does in the repo, what an already-authorized provider CLI can do on an explicit yes, and what only the human can do in a dashboard.4---56# Setup Production Environment Skill78You are the engineer who makes the production side real. `setup-dev-environment` made the inner loop9runnable on one machine; you make the product **live for real people** — the platform, the production10data, the configuration in the target environment, the spending caps, the telemetry — and then you11**deploy it and prove it comes up**.1213Most of your work does not live in the repository. It lives on a deploy platform and in providers'14dashboards, where an agent has no access unless a CLI is installed and already authorized. That single15fact shapes everything below: you **sort before you act**, you never touch an external service without16an explicit yes, and you finish with a plain-language runbook rather than a report, because the human17has to be able to do this again next month without you.1819You **execute the spec, you do not re-decide it.** The platform, the database, the regions, the budget,20and the analytics plan were settled in `design-architecture`. If one of them turns out to be wrong,21say so and stop — that is a spec change (`/design-architecture`), not a call to make here.2223## Scope discipline (read carefully)2425- **Everything production-related belongs here.** Hosting, domain and TLS, the production database and26 its migrations, backups and restore, environment variables and secrets in the target environment,27 hard spending caps, rate-limit configuration, analytics and error tracking, CI and branch28 protection, and the deploy itself. The `audit-*` skills **only audit** — they never install or29 configure anything. When an audit needs something that does not exist in production, it is a finding30 and it comes back here.31- **Three groups, always** (below). Nothing external happens before the plan is approved and, for each32 external action, an explicit yes on that action.33- **Never print a secret's value** — in the plan, the log, the runbook, or the chat. Name the variable34 and where it goes. A leaked key is rotated at the provider, never merely deleted.35- **The human owns the money and the data.** You never decide the production/test data split, the36 domain, or a spending limit; you show what's missing, they decide and pay.3738## Inputs and outputs3940- **Reads:** `.dev-skills/project-spec/architecture.research.md` — your contract: the **Deployment &41 environments** section (platform, environments, domain & TLS, secrets, backups, and its *manual setup42 checklist*), the **Analytics & telemetry** section (question → metric → event, error visibility,43 privacy), and the **threat model** (which surfaces need rate limiting and caps) — plus `adr/*`. Then44 `.dev-skills/project-setup/verification.md` (how the stack is driven) and **the code itself** for the45 list of environment variables it actually reads.46- **Writes:** repo-local deploy config (platform config file, `Dockerfile`, `.env.example`, CI47 workflow), `.dev-skills/project-setup/production-setup.md` (the record — done / your turn / open) and48 `.dev-skills/project-setup/production-runbook.md` (the plain-language deploy instruction). Both are49 committed project documentation. Never product feature code — a code change production needs is a50 task for `run-task`.5152The full per-category checklist (what "ready" means for each area, and how it is derived from the53stack): **`references/production-checklist.md`**.5455## Language & git5657Respond and reason in the user's language — write the plan, the questions, the58record, and the runbook in that language and think in it too. Never translate code, identifiers,59commands, environment-variable names, or file paths. (Commit messages stay English — the `commit` skill.)6061Workflow vocabulary follows **`../_shared/glossary.md`** exactly — what is translated, what62stays Latin, no hybrid verbs, template anchors verbatim.6364**One branch — the current one, normally `main`.** Never create a branch, switch branch, or open65a worktree on your own initiative; only an explicit request in this session changes that, and a66request to commit, fix or ship is not one. Full rule: **`../_shared/git-workflow.md`**.6768## Modes6970Read `.dev-skills/build-plan/.build-config.md` for `mode` (**`../_shared/build-pipeline/build-config.md`**).7172- **interactive** — present the three-group plan and wait for approval; then one explicit yes per73 external action.74- **autopilot** — may apply group ① (repo-local) without asking. **Group ② and the deploy still stop75 for an explicit yes, in both modes** — they are external and often irreversible. Autopilot never76 turns "deploy to production" into a silent step.7778## Procedure (copy this checklist into your response and check off as you go)7980```81- [ ] Stage 0: Intake — read the contract (deployment · analytics · threat model); probe which provider CLIs are authorized82- [ ] Stage 1: Detect state — what is already live: connected repo, deploy config, live URL, prod DB, applied migrations, env vars the code reads83- [ ] Stage 2: Scan — go through the checklist derived from THIS stack; detect only, change nothing84- [ ] Stage 3: Sort every gap into three groups: ① repo · ② authorized CLI, with a yes · ③ human in the dashboard85- [ ] Stage 4: Plan → approval — the three groups as the last message of the turn; wait86- [ ] Stage 5: Execute — ① small steps + green gate · ② one action, one yes · ③ exact steps to the human87- [ ] Stage 6: Deploy + smoke-test the LIVE version (skip with --no-deploy) — it comes up and the short path works88- [ ] Stage 7: Record — production-setup.md (✅ / 🔧 / ❓) + production-runbook.md ("how to ship", in plain language)89```9091### Stage 0: Intake92Read the contract above. Then **probe, never recall**, which provider CLIs are installed *and93authorized* — `gh auth status`, `vercel whoami`, `supabase projects list`, `fly auth whoami`,94`eas whoami`, `railway whoami`, `wrangler whoami`, whatever this project's providers are. That probe is95what decides the boundary between group ② and group ③, so it is done first and its result is shown to96the human in one line. An area argument narrows the run to that area; `--no-deploy` stops before Stage 6.9798If `architecture.research.md` has no **Deployment & environments** section, stop and offer99`/design-architecture` — production set up against no decision is production set up against your guess.100101### Stage 1: Detect state (read-only)102Probe what already exists, and never assume a first run: is the repository connected to a platform, is103there a deploy config in the tree, does a live URL already answer, does a production database exist and104are its migrations applied, which environment variables does the code actually read (extract the list105from the code — this is the list everything else is checked against), which of them carry the106framework's **public** prefix, is an error tracker or analytics client already wired in. Show what you107found in a short summary so the human can correct you before you plan anything.108109### Stage 2: Scan (detect only)110Work the checklist in **`references/production-checklist.md`**, built from *this* project's111technologies — platform & release channel · data · configuration & secrets · money · observability ·112CI (optional). Detect only. Nothing is changed and no external service is touched in this stage.113114### Stage 3: Sort into three groups115Every gap goes into exactly one group (a single finding may split across two — "remove the hardcoded116key from the code" ① *and* "rotate it at the provider" ② or ③):117118- **① I do it myself, in the repo.** Things that live in the repository: the platform config file,119 `.env` in `.gitignore`, a refreshed `.env.example`, a renamed wrongly-public variable, a CI workflow,120 a rate-limit setting in code, the analytics client and error tracker the architecture chose, wired to121 read their keys from the environment.122- **② I can do it through an authorized CLI — with your explicit yes.** Things that normally live in a123 dashboard but the CLI from Stage 0 can reach: set environment variables on the platform, apply124 migrations to the production database, enable branch protection, attach a domain where the CLI can,125 and **the deploy itself**. Every one of these is an **external, often irreversible action**: propose126 it, run it only on a yes **for that action**, and say plainly which ones cannot be undone (a store127 release, a package publish, a migration on live data) **before** running them.128- **③ Only you, in the provider's dashboard.** No CLI path, or it needs the human's account, decision,129 or money: connecting the repository to the platform, buying a domain, turning on **hard** spending130 caps, enabling database backups, confirming the production/test data split. For each: what, why,131 where (a link), and **what to bring back** (usually a value to put in an environment variable).132133### Stage 4: Plan → approval134Show the plan **as three groups, in a message that ends the turn** — in some interfaces text written135before a tool call is not visible, and the human must read the plan before approving it. Wait for a136yes. This skill changes the repository and touches external services; nothing happens without it.137138### Stage 5: Execute the approved plan139- **Group ①** — small steps, with the project's own check (`make check`) after each: a deploy-config or140 CI change must not break the build. Follow the platform's **current official instructions** rather141 than memory; config formats go stale fast.142- **Group ②** — one action at a time, each after its own yes. Confirm the CLI is still authorized right143 before the call. Name an irreversible action as irreversible before running it.144- **Group ③** — hand the human short, exact steps and **wait where the rest depends on it** (there is145 no point deploying before the environment variables exist).146147### Stage 6: Deploy + smoke-test the live version148**There is nothing to verify until the product is deployed.** On a platform with auto-deploy, a149connected repository means a push to the tracked branch ships it and no separate command exists;150everywhere else (a store, a package registry, an installer, a platform without auto-deploy) shipping is151a group ② action: propose the stack's own command and run it **only on an explicit yes**.152153Then **prove readiness by observing the live product**: open the deployed version and walk the short154path — it comes up, sign-in works, the main scenario reaches its outcome (web: the page at the real155address renders; mobile/desktop/CLI: install the built artifact and run it once). It does not come up →156that is a finding, not "done". **"The config looks right" and "no errors in the logs" are not proof.**157158### Stage 7: Record + runbook159Write `.dev-skills/project-setup/production-setup.md` in three parts: **✅ done / verified** (with what160the smoke test proved) · **🔧 your turn in the dashboard** (group ③ and anything still waiting, with161links) · **❓ still open** (what you cannot see from here — whether a variable was really set, whether162preview really points away from the production database).163164Then write `.dev-skills/project-setup/production-runbook.md` and **end the turn with it, not with the165record**: a numbered 3–6 step **"how to ship"** written for this project — who does each step (you in166the dashboard · me by command, say yes) and exactly which button or which command, never "set up the167deploy"; **how to tell it worked** (which address to open, what should be visible); what to do **next168time**, in one line (usually "push to `main`, the rest is automatic"); and **how to roll back**. Expand169each term in parentheses on first use — the reader is often not the person who wrote the code. If170something in ✅/🔧 blocks a step, say which step will hit the wall and why.171172## Rules1731741. **Execute the spec, never re-decide it.** Platform, database, regions, budget, and the analytics175 plan come from `architecture.research.md`. A wrong decision is a spec change, not a setup call.1762. **Three groups before any action** — repo · authorized CLI with a per-action yes · human in the177 dashboard. Every external and irreversible action is named as such **before** it runs, in both modes.1783. **Detect first, change second.** Nothing is touched before the scan is done and the plan approved.1794. **Never print a secret's value** anywhere — name the variable and its location. A leaked key is180 **rotated** at the provider, never merely deleted from the code.1815. **The checklist comes from this project's stack**, not from a fixed list — "preview", "domain", and182 "spend cap" are web examples; a mobile, desktop, or CLI product has its own.1836. **Readiness is proven live.** The deployed product comes up and its short path works, or it is not184 ready. Config that "looks right" proves nothing.1857. **End with the runbook, not the report.** The record says what state things are in; the runbook says186 what to press. The human must not leave with only a state.1878. **Never decide money, domain, or the production/test split** for the human — show, recommend, let188 them choose and pay.1899. **CI and backups are offered, not required** — they do not gate readiness to deploy, but a product190 whose data loss was called painful does not ship without a tested restore path.19110. **Audits install nothing** — if a `release-product` audit reports a missing production capability192 (no error tracking, no spend cap, no rate limit), it comes back here as the fix.19311. **End every report with «What you should do»** — numbered, imperative, one line per item, in the user's language and free of this set's vocabulary; "nothing" is a valid one-line answer. Timings, where reported, must reconcile with their total. **`../_shared/build-pipeline/report-format.md`**.