The screen is the JSON.
Search fields, columns, buttons and the API behind the rows all come from one document. Point at a key to see where it lands.

Architecture
Studio writes JSON, runtime renders it
The studio keeps metadata in MySQL and publishes JSON documents to an appdata volume served at /resources. The runtime reads only those, so published apps keep working with the studio's database down.
From a designed page to a running one
Publishing is one request: the server runs the numbered steps under a per-file lock, and a stale designer gets the newer document back (dashed). The runtime resolves APIs by name, hosts from env.json, and runs designer code with globals shadowed.
Publishing in one locked step
async publish({ config, logger, backup }) {return withLock(pageKey, async () => {const stored = await read(pageKey)if (stored.version > config.version)return CONFLICT(stored) // someone published firstconst next = { ...stored, ...config, version: config.version + 1, status: ONLINE }if (backup) await write(backupKey(`${Date.now()}.json`), next) // the server names itawait db.transaction(async (t) => {await PageLogger.create(logger, t); markOnline(page, app, t)await write(pageKey, next) // temp file + rename})})}The server holds a per-file lock for the write only — pages stay unlocked while being designed. If someone published first, the newer document comes back; the file is written inside the transaction, so a failed write records nothing.
The stack, layer by layer
Each band owns what sits inside it; arrows run in the direction work travels.
From an endpoint to a live screen
One unit of work, from entry to the point someone reads the result.