What stops a bad edit, and what records it.
The AI works through named operations, in transactions you can preview, under permissions the platform enforces — and everything it does is written down.
Governance here is not a review step bolted on afterwards. It is the shape of the only door the AI can use.
Maps, not JSON
Agents never see raw solution, form, workflow, grid, or screenflow JSON. Reads return compact structural maps — labels, ids, relationships. Writes are named for the change they express: add-field-to-form, update-drawer, set-object-permissions.
The one carve-out on reads is get-field-detail, which returns a stripped view of a single field so update-field can change it. There is still no operation that accepts arbitrary code or an arbitrary document and applies it to your backend. Custom frontends are the stated exception: there the agent writes React source, which is versioned, built, and promoted through the same role gates and deployment log — and which cannot run server-side code.
That is the whole point of the contract. An agent can be wrong about what field to add; it cannot be creative about how the platform stores it.
Transactions: stage, preview, commit once
begin-solution-editopens a working copy. Only one transaction can be open per solution.- Staged operations accumulate against the working copy — nothing has touched the stored solution yet.
preview-solution-editreturns a human-readable, entity-level diff of what will change. Not a JSON patch: a list a reviewer can read.diff-against-storedis a three-way drift check — if the stored solution moved underneath the transaction, you find out before commit, not after.commit-solution-editwrites the whole batch once, so the record shows one authored change rather than forty.rollback-solution-editends the transaction with nothing written at all.
Two guardrails run underneath. An abandoned transaction rolls itself back after sixty seconds of inactivity, so an agent that stops mid-thought leaves nothing half-applied. And while a transaction is open, out-of-band writes to that solution are blocked (concurrent_mutation_blocked), so nobody edits around it.
Uncommitted staged edits live in memory on the MCP server. They are not durable across a restart — commit is what persists.
The freeze flag
Every solution carries an allowMcpEdits flag. Set it off and every AI write to that solution fails with a recognizable 403 — a human-only window for a production-critical app during a change freeze, an audit, or a launch weekend. Humans keep working; agents are read-only until you flip it back.
The flag does not travel between environments: a solution that moves arrives unfrozen. Set it again on the environment you are protecting, and check it after every transfer — that way a freeze never leaks silently in either direction.
Groups and permissions, evaluated server-side
Inside a platform app, groups gate what an end user can see and do: drawer entries, screenflow actions, and grid views. A gated action is not merely hidden — the button disappears and the dispatch is rejected on the server if someone calls it anyway. There is a system Everyone group; everything more specific is yours to define, and the agent sets it up through create-group, add-users-to-group, and set-object-permissions like any other operation.
RBAC on the promotion chain
Custom frontends move through a strict, one-way chain: develop → staging → production. Skipping a tier is refused (409); promoting backwards is refused (400). Roles are per app:
- Owner — everything, including promote to production and roll production back.
- Editor — deploy to develop and promote to staging.
- Viewer — read: file tree, versions, deployment history.
↩ rollback · production promote and rollback owner-only · non-destructive
Platform apps publish differently, and we do not conflate the two: publish-solution copies the working copy to Testing and Production in one step, gated by group permissions rather than a staging approval. Frozen backup snapshots are taken deliberately, kept for branching and restore, and never published from. The transaction preview above is the review point for platform edits.
Audit logs
- Append-only deployment log. Every deployment for a custom frontend is a row that is never rewritten: which version went to which environment, who triggered it, when, with what status and error, and the deployed URL. A frozen snapshot of the build environment is stored per deploy, so “why did v15 break?” has an answer.
- Row-level instance change log. A form can enable an object change log; agents and humans read it per record through
get-instance-changelog. - Tool-invocation recording. Every MCP tool invocation is recorded. Agents can file
report-feedbackwith their recent calls attached, and a human QA queue reviews it. We present this as what it is — an audit and quality trail of what the agent did — not as monitoring of the people using it.
Who can read them: deployment history and object change logs are readable through the API and the desktop app by the app’s members. Tool-invocation records are held on our side; there is no customer-facing export, log streaming, or SIEM feed today. If your review needs one, raise it during procurement and we will answer in writing.
Single-writer edit lock
Humans and agents co-edit a custom frontend safely because writes require the app’s edit lock: one writer at a time on a 120-second lease refreshed by a 30-second heartbeat, and a 423 for anyone else who tries to write. Reads are always free, and explicit takeover is supported so a stale lock cannot hold an app hostage.
This is a pessimistic, one-writer model. We do not claim multiplayer editing; we claim that two parties cannot clobber each other.
A governed edit, logged
What a reviewer sees after an agent adds a photo-evidence field to an inspection form: identity checked, tenant chosen, changes staged, diff previewed, committed once.