Explanation: Backend Authority
Gessa is a cloud-authoritative world engine. The single most important rule in the whole system — the one every other contract leans on — is that the backend owns the truth and the frontend is a projection of it. This page explains what that means, why the engine is built this way, and how the rule is enforced rather than merely encouraged.
The framing throughout is closer to the API discipline of Stripe, Kubernetes, and Temporal than to a typical browser app. That comparison is deliberate: the v1 engine closure context dump sets the engineering bar at "contract-closed, versioned, proof-gated architecture," not "the UI looks like it works."
The frontend is a non-authoritative projection over backend authority. It may be optimistic, cached, offline-capable, and fast, but it never owns schemas, defaults, validation rules, mutation rules, or final truth. The end-to-end runnable status of this contract tracks the v1 readiness ledger, where it currently sits under the platform.ontology.control_plane and authoring.transaction.kernel rows — both unaccepted.
The core invariant
The Gessa frontend is a non-authoritative projection over backend authority. The client renders what authoritative state says is true; it is never a second source of truth. From the closure context dump, the frontend:
- may be optimistic, cached, offline-capable, beautiful, and native-feeling;
- may keep local UI state and pending operations;
- must not own independent schemas, defaults, mutation rules, validation rules, or final truth.
The client does not get to decide what a valid component, script, world, asset, or runtime state is. It projects canonical contracts, sends canonical commands, renders backend receipts, and reconciles from authoritative events. That is the entire job.
This is not an aesthetic preference. A world in Gessa is a persistent, stateful environment — see The Project Graph — and persistent state with two writers that disagree is corruption waiting to happen. The discipline exists so the system has exactly one writer of record.
One mutation authority
Every change to a world flows through a single mutation authority, expressed as canonical verbs in the Action Catalog. The human UI, MCP tools, the SDK, and AI agents all travel the same authoritative path. There is no privileged side door, and no surface can do something the others structurally cannot.
Concretely, normal authoring mutations resolve to actions like project.entity.create, project.entity.component.set, project.script.create, and project.script.patch.apply — and even those are surface verbs over the deeper Project Graph authority. The intended end state, captured by the authoring.transaction.kernel ledger row, is that:
Normal frontend, AI, MCP, SDK, and package authoring mutations converge through one backend-authoritative transaction kernel with version guards, idempotency, conflict policy, and receipts.
project.entity.component.set project.entity.component.set, project.script.patch.apply project.script.patch.apply, and the other project-graph and script-authoring verbs are the canonical surface; their definitions, owners, and exposure flags live in the generated Action Catalog.
Raw graph writes bypass authority and validation, creating a second, unvalidated source of truth. Use the Action Catalog or Script Semantic Patch instead. The project.transaction.apply verb exists, but its exposure is workflow-only precisely so that no normal UI/AI/SDK surface hand-builds graph transactions; it is an internal authority primitive, not a creator API.
Optimistic, but reconciled
Non-authoritative does not mean slow. The frontend is allowed — encouraged — to be optimistic. The honest version of optimism has a feedback loop: the client predicts, the backend rules, and the client reconciles to the backend's verdict.
The lifecycle of a normal edit:
- Project from contract. The UI is generated from canonical contract data (component schemas, action definitions, generated SDK declarations), not from a second frontend schema.
- Command. The user gesture is turned into a canonical action and sent to the canonical API. The command client carries a version coordinate and, for retry-sensitive mutations, an idempotency key.
- Optimistic overlay. The UI may immediately show the predicted result as a pending overlay so the interaction feels instant.
- Receipt and event. The backend validates, applies the mutation against the authoritative Project Graph at a known revision, and returns a receipt; authoritative state replicates to clients as events.
- Reconcile. The client replaces its optimistic overlay with the backend truth. If the backend rejected or adjusted the edit, the UI reflects the authoritative outcome and surfaces a structured diagnostic — it never silently keeps a value the backend refused.
The reconcile step is what makes the difference. An optimistic UI without reconciliation is just a second source of truth with extra latency.
Good vs bad frontend architecture
The closure context dump draws this contrast directly. A good frontend is a projection plus a command client plus a reconcile loop. A bad frontend invents its own schema and writes the graph.
GOOD — projection over authority
generated/contract data ──▶ UI projection
│
user gesture ─────────────▶ command client ──▶ canonical action API
│ │
│ ▼
optimistic overlay backend validates,
│ applies at revision,
│ emits receipt + event
▼ │
reconcile from ◀───────────────┘
backend truth
BAD — frontend as a second authority
frontend schema/defaults ──▶ raw graph mutation ──▶ backend rejects
or partially accepts
│
▼
drift, flicker, lost edits,
"the UI offered a field the
backend cannot accept"
The single rule that collapses the bad path: the frontend must never expose a button or field that the backend cannot accept through a canonical user-facing operation. If a control exists, a canonical action must back it. If no action backs it, the control must not exist.
Why it matters
The payoff of one source of truth and one mutation authority shows up everywhere downstream.
- Determinism and trust. Authoritative state replicates to clients; clients re-derive, they do not invent. Two tabs, two collaborators, and a reconnecting session all converge on the same truth because there is only one truth to converge on.
- Reconnect and reload safety. A dropped Play session re-syncs to the authoritative snapshot rather than trusting stale local state. Reload-during-save is safe because the save is a backend transaction with a revision, not a client guess.
- Conflict handling without spam. Because edits apply at a known Project Graph revision, the backend can detect and resolve conflicts under a declared policy and return a structured diagnostic, instead of leaking raw revision-conflict errors for ordinary gestures.
- AI reliability. Agents propose changes through the same actions and semantic patches humans use, so their edits are validated, audited, and reproducible. An agent cannot reach a privileged write path that a human cannot, and vice versa. This is the whole reason AI is treated as a participant in the contracts rather than a duct-tape path around them.
- Versioning and idempotency. A mutation that carries a version coordinate and an idempotency key can be retried safely and can detect parameter mismatch, the Stripe-style property the engine targets for every normal mutating command.
How this is enforced
This is a contract the engine intends to prove, not a slogan. Enforcement lives in the v1 readiness machinery rather than in prose:
- The mutation-authority and version-coverage proof classes in the proof registry require that each mutable concept has exactly one canonical authority with forbidden bypasses tested, and that owned contracts carry version coordinates.
- The
authoring.transaction.kernelandplatform.ontology.control_planerows in the feature ledger carry the single-authority claim, its required proof classes (mutation-authority,idempotency,compatibility,independent-audit, and more), and its current status. - Canonical authority bindings are recorded in
MUTATION_AUTHORITY_REGISTRY.jsonunderdocs/cycles/v1-engine-readiness-loop/, the registry a futurecheck:v1-mutation-authoritygate validates.
Acceptance requires that the row's mutable concepts have one canonical authority and that forbidden bypasses (raw frontend mutation fetches, raw AI/MCP/SDK low-level writes, raw Project Graph transaction bypass) are tested or documented. Two normal surfaces writing the same concept with different rules is insufficient evidence. Every relevant ledger row is currently unaccepted; the single-authority rule is the contract model the engine is closing toward, not a guarantee that every path is already proven.
Pre-launch stance
The engine has never launched. Every row in the v1 readiness ledger is unaccepted. Backend authority is the architecture the engine is built around and the bar every row must clear, not a capability this page claims is already proven end to end. When you read "the frontend reconciles from backend truth," read it as the canonical contract whose runnable status is tracked by the ledger — the same honesty discipline described in Playability Proofs.
Source
Background and intent: docs/architecture/v1-engine-closure-context-dump.md (Frontend Stance and "Good/Bad frontend architecture") and the v1 engine readiness master closure contract. Enforcement coordinates live in MUTATION_AUTHORITY_REGISTRY.json and the proof/feature registries under docs/cycles/v1-engine-readiness-loop/.
Related
- Explanation: The Project Graph — the authoritative world/resource model this authority writes.
- Explanation: Script IR and GessaScript — how behavior edits stay inside one authority via Script Semantic Patch.
- Explanation: Playability Proofs — why a rendered scene is not a proven capability.
- How-To: Edit Components — editing through canonical authoring, not raw graph writes.
- Reference: Action Catalog — the canonical verb registry.
Status: stable explanation page for engine v1. The contract it describes is real and is the foundation of the engine; its end-to-end proven status tracks the v1 readiness ledger, where the governing rows are currently unaccepted.