./setup. The Developer Guide walks you from a blank Mac to your first merged story, starting with Set up your machine. Setup installs every tool, signs you in to AWS, writes each checkout's .env from the team's secrets, runs the app locally in Docker with demo data, and builds your machine its own AWS stage.This page covers working with your machine's own AWS stage day to day. Most work needs no AWS stage at all; the local Docker app that setup starts is enough. New to the codebase? Read How DevStride Is Built, and Why first. The next page, Introduction to the ds CLI, explains the -u/-b flags and the bind cache used below, and the Command Reference has every flag.
Setup's stage step builds it for you: its own copy of the demo data on a Neon database branch, its config, its first deploy, migrations and demo logins. It is named after your machine, and the machine's secrets bundle records it, so you set nothing by hand. ds machine ready proves it on every run (stage: recorded, stacks, config, database). Your AWS stage in the guide explains what it is.
Run a pool checkout against the stage instead of Docker:
ds pool cloud wt1 # starts ds run backend (sst dev, live Lambda) and ds run ui for wt1, in the background
ds pool cloud wt1 --off # stops both and brings wt1's Docker app back
It checks your AWS sign-in first and never opens a login, refuses the shared dev and prod stages, and runs one checkout per machine. The UI runs on the checkout's own frontend port; the logs are .ds/pool-cloud-*.log in that checkout. You need to hold the checkout's lease (ds pool checkout wt1 --purpose <what>).
Setup never redeploys your stage when develop moves on. When ds machine ready notes that the stage's database is behind your checkout's code, bring it level from that checkout:
DEVSTRIDE_STAGE=<stage> DEVSTRIDE_REGION=us-east-1 ./ds -b migrations run
ds migrations run applies the expansion chain then the contract chain; ds migrations run-sql is the same command under an older name. The deploy pipeline runs the two chains separately (run-sql-expand, then run-sql-contract after the code switch). Use ds migrations run locally.ds script set-configA deployed stage never reads .env. Its secrets come from one SST secret, DEVSTRIDE_CONFIG, which setup pushed when it built the stage. When a value changes (a new key in .env after ds secrets pull, or a new setting you added to the schema in backend/src/libs/domain/config.ts and to cli/commands/scripts/set-config.ts), push it again and restart the backend:
DEVSTRIDE_STAGE=<stage> DEVSTRIDE_REGION=us-east-1 ./ds -b script set-config
ds script set-config is a one-way push from your local .env up to SST. It validates that every required value is set, then writes the DEVSTRIDE_CONFIG secret (base64-encoded JSON) your stage reads at runtime. If a value in .env changes, including when ds secrets pull rewrites it, re-run it for the change to take effect. A value that only names a resource (a bucket, a URL) can be an sst.Config.Parameter instead, which is included automatically.The test-mode Stripe keys come from the shared bundle through ds secrets pull. Your stage needs its own webhook:
https://api-<stage>.devstride.dev/v1/subscriptions/stripe/webhooks, listening for charge.refunded, charge.refund.updated and refund.updated on your account. The webhook only records refunds; DevStride runs everything else about billing itself.pbpaste | ds secrets set machine STRIPE_WEBHOOK_SECRET), run ds secrets pull, then re-run set-config as above.Setup runs these for you; use them directly when you need to:
ds stage create --member wt1 --dry-run # what making (or finishing) this machine's stage would do
ds stage create --stage <its name> --member wt1 # adopt a stage made by hand before setup made them
ds stage remove --dry-run # what removing it would delete; without --dry-run you retype its name
ds stage remove is permanent: the stage's stacks, its config, its Neon branch and its data and sign-in users all go. An admin removes a retired machine's stage with ds stage remove --machine <its name> (For admins).
The backend test suite needs Docker: its global setup creates a Postgres and a DynamoDB test container for this checkout on first run (drizzle-tests and dynamodb-tests in a plain checkout; devstride-<slug>-… inside a worktree instance, which ds worktree ls names).
cd backend && pnpm test:suite:ci:non-golden # the standard suite (golden excluded)
pnpm --dir backend exec vitest run tests/suits/path/to/test.spec.ts # one file
test script is vitest with no --run, so pnpm test -- <path> does not run one file — it starts the entire suite in watch mode and never exits, with no output. Always carry vitest run (or use a test:suite* script), and use --dir backend rather than cd backend && when running vitest directly: there is no root vitest config, so a bare pnpm exec vitest from the repo root cannot resolve the @/… path aliases../ds resolves and runs a command, and the flags used aboveds command, by categoryFor the agent-assisted workflow and current plugin references, see AI Development.
How DevStride Is Built, and Why
The idea behind how DevStride is planned, built, reviewed and released — mostly by Claude Code agents walking a plan one item at a time — and why each rule exists. Read this before the mechanics.
Introduction to the ds CLI
What the ds CLI actually wraps, how ./ds resolves and runs a command, the global auth/bind flags, and the eighteen real top-level commands.