The Command Center's live switches
What decides whether each Command Center section shows sample rows or real data, and the jobs that
fetch the real data. The switches are the API's environment variables, not controls in
the app, and changing them on a deployment is governed:
The Command Center → Going live. Running and deploying
the app itself is in apps/command/README.md.
command.useclear.org is deployed from the dev branch, so what it shows is testnet and
sandbox data. The project's main branch is kept for real money.
The first admin comes from COMMAND_ADMIN_EMAILS, a comma-separated list on the API. A person
who signs in with one of those emails and has no Command Center record yet is created in the Admin
group, and the audit log records it.
Three layers
1. The app never draws sample data. At start-up the app empties every dataset it was designed
with, then fills in what the API sends; what the API does not send stays empty, and the page says
so (live/empty.ts). Only a development build opened with
?preview=1 shows the design's own rows. What the app keeps is not data: labels, layout, and the
co-op's structure as the API writes it.
2. The API's tables are seeded only when asked. COMMAND_SEED=on fills the Command Center's
empty tables at start-up with the sample rows in
packages/command-types/src/fixtures. It fills a
table only when it is empty and a figure only when it is missing, so it never overwrites what a live
job wrote. Any other value, or none, seeds nothing. The structure (the contracts map, the entities,
the boards' seats) is written into empty tables either way, and the audit log is never seeded.
3. Each section reads seed or live. PROVIDER_<SECTION>=live switches one section to its
live sources; anything else, or nothing, leaves it on seed
(sections.ts). On seed a section reads the
Command Center's own tables, seeded or empty, as of the sample data's fixed day. On live it reads
its live sources as of today.
What each switch changes
live readsPROVIDER_MONEYOffersIssuer line. The feeds: the bank and payouts from Plaid and Stripe, card spend from Lithic, deposits moving through BridgePROVIDER_CONTRACTSPROVIDER_SHOPPROVIDER_MEMBERSPROVIDER_MERCHANTSPROVIDER_GROWTHPROVIDER_FIELD, PROVIDER_GOVERNANCE, PROVIDER_RECORDS, PROVIDER_HOMElive changes only the day they are read for, to todayOther sections follow these switches:
- Home counts members from the member app when Members is live, and shows Growth's live visits.
- Governance counts members' acceptances of the app's documents when Members is live.
- Money and Contracts read Base Sepolia only. It is the only address book in
packages/command-types/src/chain.
What actions do
Some actions behave differently on each side:
seedliveWhich actions need a second person is in The Command Center → The two-person rule.
The jobs behind the live sources
The API runs these after its migrations. Each can be turned off, and each says at start-up whether it is off and why.
COMMAND_FEEDS=offCOMMAND_INDEXER=offCOMMAND_INDEXER_MINUTES (5) and on demand. History beyond the last 20,000 blocks comes from Etherscan V2 when ETHERSCAN_API_KEY or COMMAND_HISTORY_API_KEY is set, else Blockscout; COMMAND_HISTORY_API=off skips itCOMMAND_GITHUB=offCOMMAND_GITHUB_REPO on COMMAND_GITHUB_BRANCHES; GITHUB_TOKEN raises GitHub's rate limitCOMMAND_INVITES=offCOMMAND_GEOCODE=offThe feeds
plaidCOMMAND_PLAID_HOURS), and when Plaid's webhook or a Stripe payout wakes itPLAID_CLIENT_ID, PLAID_SECRET, the token envelope keyPLAID_ENV is not sandboxbridgeCOMMAND_FEEDS_MINUTES)BRIDGE_SANDBOX_API_KEYBRIDGE_ENV is not sandboxlithicLITHIC_API_KEYLITHIC_ENV is not sandboxstripeCOMMAND_STRIPE_KEY, else STRIPE_SECRET_KEYshopCOMMAND_SHOP_STRIPE_KEY, else SHOP_STRIPE_SECRET_KEYcatalogCOMMAND_SHOP_CATALOG_URL (the site's catalog unless set); COMMAND_CATALOG_TOKEN to include draftsoffsite, appsCOMMAND_SITE_MINUTES)UMAMI_API_URL, UMAMI_USERNAME, UMAMI_PASSWORD, and the site's or apps' website idsThe money feeds read sandboxes only. Plaid, Bridge, Lithic and Stripe each call their
provider's sandbox or test mode, and each turns itself off when given a live key
(feedSources.ts). With PROVIDER_MONEY=live
on a deployment holding live keys, the chain's figures are live and the bank, card, deposit and
payout figures stay empty: there is no production path for them yet. Only the shop's feed takes a
live key.
The Plaid feed makes its own bank link, once, with Plaid's sandbox-only call: a sandbox
institution (COMMAND_PLAID_INSTITUTION) and a starting balance (COMMAND_PLAID_SANDBOX_BALANCE).
It registers COMMAND_PLAID_WEBHOOK_URL as the link's webhook, which should be the API's
/api/command/webhooks/plaid; that route checks Plaid's signature
(Going live → Webhooks).
The Ops Safe is set by COMMAND_SAFE_ADDRESS, COMMAND_SAFE_CHAIN_ID, SAFE_TX_SERVICE_URL
and SAFE_API_KEY. Without an address, Build says no Safe is connected and nothing can be prepared
for signing.
Seeing which are on
GET /api/command/feeds (Home at Totals or above) returns each feed's health: synced, behind,
failing with its error, off with the reason, or never run. The menu's foot draws it and
reads it again every 5 minutes. No endpoint reports a section's PROVIDER_ value; it is whatever
the API's environment says.
Because they are environment variables, a change takes effect when the API restarts with it.