Test and live

The running jobjob_7Hq2 · accepted · document.fr-CA.pdf · $49.00 final

Every brand runs in two modes at one address, and the key picks the mode, with the same simulation on your machine before either. Test mode simulates AI, money, outside systems and members, takes magic values that pick each branch, and runs on test clocks, so a whole season runs before a buyer sees it. Every key runs in test on every plan.

Test mode answers one question: does every branch of the Service work before anything real happens? A brand serves both modes at the same address. An sk_test_ key reaches test mode and an sk_live_ key reaches live, and no job, member, subject or dollar ever crosses between them.

On your machineTest modeLive
Versionyour folder as it stands, reloaded on savethe newest tested versionthe version deploy --live promoted
Served byservices.dev dev, at localhost:8787your brand's address, to sk_test_ keysyour brand's address, to sk_live_ keys
AIsimulatedsimulated, unless you set --model live on a test keyyour model key, at cost
Moneyrecorded, never moved, and no Striperecorded on the ledger, never movedcharged, released, refunded and paid out on your Stripe account
Outside systemsthe sandbox, steered by magic valuesthe same sandboxthe real endpoint and its receipt
Membersthe simulated marketthe simulated market, and your staffthe people in your Pool
Timeyour clock, or a test clockthe brand's clock, or a test clock you advancethe brand's clock
Every answercarries simulated: truecarries simulated: truecarries simulated: false
Planevery key, on every planevery key, on every planeach key on the plan that carries it
DeployServes atPlan
test and live<brand>.builder.domainsevery plan
your own domainBrand.domain, with its certificate renewed for youLaunch
a preview of a branchservices.dev preview, on test keys, at its own addressTeam
private, in your regionservices.dev deploy --region eu, data kept thereScale

A magic value makes a job take one branch with no person and no outside system: a party who never answers, a filing rejected once, a member whose coverage lapsed. Set it on the order's metadata.sandbox, as a party's email, or on a test clock for every job it holds. The reference lists all of them and the pages that show each one.

apis.tax runs its whole spring before February. A test clock carries its own market, here 40 simulated preparers who ask more than reviews post at:

Run
npx services.dev test-clocks create 2027-01-15 --members 40 --market tight
magic values: market = tight, metadata.sandbox.outside = reject_once
← tc_9Ts1 · test clock · frozen at 2027-01-15T14:00:00Z · market tight, 40 simulated members in preparers · test mode only
Run
npx services.dev subscriptions seed tax-plan --count 120 --test-clock tc_9Ts1
magic values: market = tight, metadata.sandbox.outside = reject_once
← 120 Tax Plans on tc_9Ts1 · 120 simulated taxpayers · entities and states drawn from the seed 9Ts1 · simulated: true

Then three months, in one call. Every rung, mint, rejection, raise and extension fires in order, the same way it would on the brand's clock. The test clock's rules and the timers it fires are on Timers and replay:

Run
npx services.dev tick 2027-04-16 --test-clock tc_9Ts1
magic values: market = tight, metadata.sandbox.outside = reject_once
apis.tax · test mode · tc_9Ts1 · 2027-01-15 → 2027-04-16 · version 2027-01 · market tight
  minted   120 annual returns on 1 Feb, one for each Tax Plan
  filed    104 federal and 212 state returns · 9 rejected once, each repaired inside its window
  extended 16 returns, by each file clock's run tentative 3d rung · 0 dates missed
  fill     113 reviews · p90 3h40m to claim · raised 38 times · widened 4 · 0 unreached
  money    recorded, never moved · 120 Tax Plan cycles, $288,000.00 · each return $0, inside its plan · signers' pay $9,420.00, preparers' $1,215.00
  every act simulated: true · nothing reached the IRS, a state, Stripe or a member

The brand's own suite runs on the same clock, as deploy runs it:

Run
npx services.dev verify --test-clock tc_9Ts1
magic values: market = tight, metadata.sandbox.outside = reject_once
apis.tax · 258 cases from 84 rows · test mode · 2027-01 on tc_9Ts1
258 passed · 0 failed · 72 live rows wait for deploy --live

The owner console shows test mode with the same screens, behind a test banner, so what you check in test is what you will read live.

Call (CLI)APIEventOn the consolePlan
test-clocks create <time> [--members N --market tight]POST /test_clockstest_clock.created/consoleevery plan
subscriptions seed <service> --count N --test-clock <tc>POST /test_clocks/:id/seedsubscription.created/consoleevery plan
verify --test-clock <tc>GET /verify/suite.jsonnone: it reads/console/deploysevery plan
dev [--port 8787]none: it serves your folder on localhostnone: it reads—every plan
previewPOST https://services.dev/v1/previewsversion.tested/console/deploysTeam
deploy --region <region>POST https://services.dev/v1/deploys { region }version.deployed/console/deploysScale