---
title: "Authoring Mutation Contracts"
description: "Sources: `packages/authoring-contracts/src/index.ts`."
engineVersion: v1.0.234
date: 2026-09-28
license: "(c) Gessa, proprietary. Cite with attribution to https://gessa.ai/docs/. Terms: https://gessa.ai/terms/."
canonical: https://gessa.ai/docs/spec/generated/authoring-contracts/
---
<!-- GENERATED FILE: do not edit by hand. -->
<!-- Regenerate with `npm run gen-docs`. -->

Sources: `packages/authoring-contracts/src/index.ts`.

# Authoring Mutation Contracts

This generated snapshot is derived from `@game-platform/authoring-contracts`. It is the canonical registry for normal authoring mutation contracts, prior-surface migration mapping, and projection coverage expectations.

Registry version: `authoring-contracts.v1.kernel-contracts`.
Registry hash: `sha256:754a6be63242524d6f06082c56d6f8c8b9e0d7d3eda5dea0b06afd773ff0724e`.
Contract count: `16`.
Prior surface mapping count: `20`.
Tool parity mapping count: `38`.
Scenario helper count: `6`.

## Contracts

| Operation | Title | Domain | Lifecycle | Input Schema | Target | Validator | Apply Target | Conflict Policy | Surface Exposure |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `project.metadata.update` | Update Project Metadata | project | active | UpdateGameRequest | project<br>game_id | control-plane<br>`ControlPlaneService.updateGame` | server/src/modules/control-plane/service.ts<br>`updateGame` | idempotent_apply | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `project.graph.transaction.apply` | Apply Low-Level Project Graph Transaction | project | active | ProjectTransactionRequest | transaction<br>transaction_ops | project-graph<br>`ProjectGraphService.applyTransaction` | server/src/modules/project-graph/service.ts<br>`applyTransaction` | transaction_rebase | frontend: exposed<br>ai: privileged<br>mcp: privileged<br>sdk: privileged |
| `entity.create` | Create Entity | entity | active | CreateProjectEntityRequest | resource<br>semantic_target | authoring-kernel<br>`AuthoringKernel.applyEntityCreate` | server/src/modules/project-graph/service.ts<br>`createEntity` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `entity.update` | Update Entity | entity | active | UpdateProjectEntityRequest | resource<br>id_or_key | authoring-kernel<br>`AuthoringKernel.applyEntityUpdate` | server/src/modules/project-graph/service.ts<br>`updateEntity` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `entity.delete` | Delete Entity | entity | active | DeleteProjectEntityRequest | resource<br>id_or_key | authoring-kernel<br>`AuthoringKernel.applyEntityDelete` | server/src/modules/project-graph/service.ts<br>`deleteEntity` | strict_reject | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `component.put` | Put Entity Component | component | active | PutProjectEntityComponentRequest | component<br>component_key | @game-platform/ecs<br>`validateComponentMutation` | server/src/modules/project-graph/service.ts<br>`putEntityComponent` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `component.patch` | Patch Entity Component | component | active | PatchProjectEntityComponentRequest | component<br>component_key | @game-platform/ecs<br>`validateComponentMutation` | server/src/modules/project-graph/service.ts<br>`patchEntityComponent` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `component.delete` | Delete Entity Component | component | active | DeleteProjectEntityComponentRequest | component<br>component_key | @game-platform/ecs<br>`validateComponentMutation` | server/src/modules/project-graph/service.ts<br>`deleteEntityComponent` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `component.field.patch` | Patch Entity Component Field | component | active | AuthoringComponentFieldPatchRequest | component_field<br>field_path | @game-platform/ecs<br>`validateComponentMutation` | server/src/modules/project-graph/service.ts<br>`applyEntityComponentAuthoringIntent` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `reference.assign` | Assign Component Reference | reference | active | AuthoringReferenceAssignmentRequest | reference<br>field_path | @game-platform/ecs<br>`validateComponentMutation` | server/src/modules/project-graph/service.ts<br>`applyEntityComponentAuthoringIntent` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `prefab.override.mutate` | Mutate Prefab Override | prefab | active | SetProjectEntityComponentOverrideRequest | component<br>component_key | @game-platform/ecs<br>`validateComponentMutation` | server/src/modules/project-graph/service.ts<br>`setEntityComponentOverride` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `script.semantic_patch.apply` | Apply Script Semantic Patch | script | active | ScriptSemanticPatchSet | script<br>id_or_key | script-semantic-patch<br>`applyScriptSemanticPatch` | server/src/modules/project-graph/service.ts<br>`applyScriptSemanticPatch` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `material.semantic_patch.apply` | Apply Material Semantic Patch | material | active | MaterialSemanticPatchSet | material<br>asset_id | material-semantic-patch<br>`applyMaterialSemanticPatch` | server/src/modules/project-graph/service.ts<br>`applyMaterialSemanticPatch` | authoring_kernel_rebase | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `workflow.definition.mutate` | Mutate Workflow Definition | workflow | privileged | ProjectWorkflowMutationRequest | workflow<br>id_or_key | workflow-ir<br>`validateWorkflowIr` | server/src/modules/project-graph/service.ts<br>`createWorkflow/updateWorkflow` | authoring_kernel_rebase | frontend: hidden<br>ai: hidden<br>mcp: hidden<br>sdk: hidden |
| `blueprint.package.apply` | Apply Smart Asset Package | template | active | SmartAssetPackageApplyRequest | template<br>template_id | blueprint-catalog<br>`requireSmartAssetPackage/validateSmartAssetPackageCatalog` | server/src/modules/creation-templates/service.ts<br>`SmartAssetPackageService.applyPackage` | idempotent_apply | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |
| `creation_template.apply` | Apply Creation Template | template | active | CreationTemplateApplyRequest | template<br>template_id | blueprint-catalog<br>`compileCreationTemplate` | server/src/modules/creation-templates/service.ts<br>`applyCreationTemplate` | idempotent_apply | frontend: exposed<br>ai: exposed<br>mcp: exposed<br>sdk: exposed |

## Prior Surface Mapping

| Surface | Owner | Normal | Contract | Status | Reason | Guard | Executable Evidence |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `frontend.inspector.component.patch` | web_client/spa | yes | `component.field.patch` | mapped | Inspector fields route through the graph edit session and canonical component field patch contract. | `check:component-authoring-kernel-boundary` | `web_client/spa/src/views/InspectorView.test.tsx`<br>round-trips component field edits through the graph edit session |
| `frontend.viewport.transform.patch` | web_client/spa | yes | `component.field.patch` | mapped | Viewport transform gestures enter the semantic transaction command as component field edits. | `check:project-graph-conflict-policy` | `web_client/spa/src/workbench-graph/edit-session.test.ts`<br>routes viewport gestures through the semantic transaction command |
| `frontend.workbench.apply_transaction` | web_client/spa | yes | `project.graph.transaction.apply` | mapped | Frontend typed graph-op batches enter the semantic transaction command and receive canonical component-kernel receipts; raw Script IR and direct AI/MCP/SDK low-level transaction tools remain privileged. | `check:frontend-authoring-surface-coverage` | `web_client/spa/src/workbench-graph/edit-session.test.ts`<br>applies all ops through semantic commands when every one is valid<br><br>`server/tests/componentAuthoringIntent.test.ts`<br>AI-surface and SDK-route clears persist the same canonical value AND emit the same receipt changedFieldPaths |
| `backend.project_graph.component.put` | project-graph | yes | `component.put` | mapped | Direct component put delegates to canonical component validation, resource admission, persistence, and receipts. | `check:component-authoring-kernel-boundary` | `server/tests/componentInstanceActionsApi.test.ts`<br>prepares and attaches 'Spatial Capture' as one committed Project Graph transaction |
| `backend.project_graph.component.patch` | project-graph | yes | `component.patch` | mapped | Direct component patch delegates to the component mutation kernel and emits its receipt. | `check:component-authoring-kernel-boundary` | `server/tests/componentAuthoringIntent.test.ts`<br>AI-surface and SDK-route clears persist the same canonical value AND emit the same receipt changedFieldPaths |
| `backend.project_graph.component.delete` | project-graph | yes | `component.delete` | mapped | Direct component delete delegates to the canonical component mutation path. | `check:component-authoring-kernel-boundary` | `server/tests/mcpServer.test.ts`<br>lets AI component tools read schemas and mutate built-in components with structural removal denial |
| `backend.project_graph.prefab.override` | project-graph | yes | `prefab.override.mutate` | mapped | Prefab override component edits use the same validation and receipt kernel as base edits. | `check:component-authoring-kernel-boundary` | `server/tests/componentAuthoringIntent.test.ts`<br>AI-surface and SDK-route clears persist the same canonical value AND emit the same receipt changedFieldPaths |
| `ai.collaborator.component.patch` | ai-platform | yes | `component.patch` | mapped | AI component edits use the same operation id, validation, persistence, and receipt as inspector/MCP/SDK. | `check:ai-mcp-sdk-authoring-parity` | `server/tests/componentAuthoringIntent.test.ts`<br>AI-surface and SDK-route clears persist the same canonical value AND emit the same receipt changedFieldPaths |
| `mcp.project_update_component` | mcp | yes | `component.patch` | mapped | MCP component patch uses the kernel conflict policy and never blind-retries a stale overwrite. | `check:ai-mcp-sdk-authoring-parity` | `server/tests/mcpServer.test.ts`<br>rebases stale AI component mutations and conflicts stale overwrites |
| `mcp.project_add_component` | mcp | yes | `component.put` | mapped | MCP component put executes against canonical Project Graph services for every public built-in type. | `check:ai-mcp-sdk-authoring-parity` | `server/tests/mcpServer.test.ts`<br>lets AI component tools read schemas and mutate built-in components with structural removal denial |
| `mcp.project_remove_component` | mcp | yes | `component.delete` | mapped | MCP component delete executes against canonical Project Graph services for every public built-in type. | `check:ai-mcp-sdk-authoring-parity` | `server/tests/mcpServer.test.ts`<br>lets AI component tools read schemas and mutate built-in components with structural removal denial |
| `mcp.project_set_component_override` | mcp | yes | `prefab.override.mutate` | mapped | MCP prefab overrides execute through the component override kernel for every public built-in type. | `check:ai-mcp-sdk-authoring-parity` | `server/tests/mcpServer.test.ts`<br>lets AI component tools read schemas and mutate built-in components with structural removal denial |
| `sdk.authoring.host.component.patch` | script-sdk | yes | `component.patch` | mapped | SDK component helpers use the canonical HTTP authoring host and component operation ids. | `check:ai-mcp-sdk-authoring-parity` | `packages/script-sdk/tests/componentAuthoringHttpHost.test.ts`<br>routes every host operation to the canonical Project Graph endpoint with version and idempotency guards |
| `backend.creation_template.apply` | creation-templates | yes | `creation_template.apply` | mapped | Creation-template chunks apply through checked Project Graph transactions in the canonical create-game backend. | `check:frontend-authoring-surface-coverage` | `server/tests/creationTemplates.test.ts`<br>creates launch templates through the canonical create-game backend path |
| `script.full_ir.update.normal` | project-graph | yes | `script.semantic_patch.apply` | privileged_only | Full IR/source update is not the normal AI/human path once semantic patch coverage exists. | `check:script-visual-source-parity` |  |
| `frontend.material_editor.pbr_controls` | web_client/spa | yes | `material.semantic_patch.apply` | mapped | PBR controls edit the material authoring document; autosave commits through the session's Material Semantic Patch path into the canonical graph. | `check:material-editor-no-slider-source-of-truth` | `server/tests/assetAuthoringApi.test.ts`<br>commits the authored material GRAPH as the SSOT: graph params win over a stale flat payload, and node positions persist |
| `backend.asset_authoring.material_commit` | asset-authoring | yes | `material.semantic_patch.apply` | mapped | Material authoring session commits persist the graph, compiled artifact, and semantic-patch receipt through the Project Graph re-entry. | `check:material-graph-contract` | `server/tests/assetAuthoringApi.test.ts`<br>commits the authored material GRAPH as the SSOT: graph params win over a stale flat payload, and node positions persist |
| `material.raw_graph.update.normal` | project-graph | yes | `material.semantic_patch.apply` | privileged_only | Raw materialGraph/artifact updates are not a normal AI/human path; normal edits use Material Semantic Patch. | `check:material-graph-no-raw-shader-authoring` |  |
| `workflow.creator.authoring` | workflows | yes | `workflow.definition.mutate` | privileged_only | Workflow definition mutation is hidden from creator frontend until a complete workflow authoring projection ships. | `check:frontend-authoring-surface-coverage` |  |
| `component.resource_admission` | ecs | yes | `component.patch` | mapped | Every component resource reference uses the same declarative evaluator for lifecycle, identity, kind, and readiness. | `check:component-authoring-kernel-boundary` | `packages/ecs/tests/componentMutationValidator.test.ts`<br>uses one generic target evaluator for lifecycle, key, kind, and resource readiness |

## AI/MCP/SDK/Frontend Tool Parity

| Surface | Entrypoint | Operation | Equivalent Mutation | Canonical | Normal | Privilege | Replacement | Scenarios | Guard |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| frontend | `AuthoringCommandClient.componentPut` | `component.put` | entity component put | yes | yes | normal |  |  | `check:frontend-authoring-surface-coverage` |
| frontend | `AuthoringCommandClient.componentPatch` | `component.patch` | entity component patch | yes | yes | normal |  |  | `check:frontend-authoring-surface-coverage` |
| frontend | `InspectorView` | `component.field.patch` | component field patch | yes | yes | normal |  |  | `check:frontend-authoring-surface-coverage` |
| frontend | `SceneInteractionLayer3D` | `component.field.patch` | component field patch | yes | yes | normal |  |  | `check:frontend-authoring-surface-coverage` |
| frontend | `VisualScriptEditorView` | `script.semantic_patch.apply` | script behavior edit | yes | yes | normal |  | `shooter`<br>`collector`<br>`score_win_state` | `check:frontend-authoring-surface-coverage` |
| frontend | `MaterialEditorView` | `material.semantic_patch.apply` | material appearance edit | yes | yes | normal |  |  | `check:material-ai-mcp-sdk-parity` |
| frontend | `ControlPlaneView.BlueprintLibrary` | `blueprint.package.apply` | smart asset package apply | yes | yes | normal |  |  | `check:frontend-authoring-surface-coverage` |
| ai | `create_project_entity` | `entity.create` | entity create | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| ai | `update_project_entity` | `entity.update` | entity update | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| ai | `put_entity_component` | `component.put` | entity component put | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| ai | `patch_entity_component` | `component.patch` | entity component patch | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| ai | `set_entity_component_override` | `prefab.override.mutate` | prefab component override | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| ai | `apply_script_semantic_patch` | `script.semantic_patch.apply` | script behavior edit | yes | yes | normal | `script.semantic_patch.apply` | `shooter`<br>`collector`<br>`door_trigger`<br>`timer`<br>`score_win_state`<br>`basic_multiplayer_interaction` | `check:ai-mcp-sdk-authoring-parity` |
| ai | `apply_material_semantic_patch` | `material.semantic_patch.apply` | material appearance edit | yes | yes | normal | `material.semantic_patch.apply` |  | `check:material-ai-mcp-sdk-parity` |
| ai | `apply_smart_asset_package` | `blueprint.package.apply` | smart asset package apply | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| ai | `create_project_script` | `script.semantic_patch.apply` | script shell create | no | no | privileged | `script.semantic_patch.apply` |  | `check:ai-mcp-sdk-authoring-parity` |
| ai | `update_project_script` | `script.semantic_patch.apply` | full script IR update | no | no | privileged | `script.semantic_patch.apply` |  | `check:ai-mcp-sdk-authoring-parity` |
| ai | `project_apply_transaction` | `project.graph.transaction.apply` | low-level transaction | no | no | privileged |  |  | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_create_entity` | `entity.create` | entity create | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_update_entity` | `entity.update` | entity update | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_add_component` | `component.put` | entity component put | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_update_component` | `component.patch` | entity component patch | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_remove_component` | `component.delete` | entity component delete | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_set_component_override` | `prefab.override.mutate` | prefab component override | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_apply_script_semantic_patch` | `script.semantic_patch.apply` | script behavior edit | yes | yes | normal | `script.semantic_patch.apply` | `shooter`<br>`collector`<br>`door_trigger`<br>`timer`<br>`score_win_state`<br>`basic_multiplayer_interaction` | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_apply_material_semantic_patch` | `material.semantic_patch.apply` | material appearance edit | yes | yes | normal | `material.semantic_patch.apply` |  | `check:material-ai-mcp-sdk-parity` |
| mcp | `project_apply_smart_asset_package` | `blueprint.package.apply` | smart asset package apply | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| mcp | `project_apply_transaction` | `project.graph.transaction.apply` | low-level transaction | no | no | privileged |  |  | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Entity.create` | `entity.create` | entity create | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Entity.update` | `entity.update` | entity update | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Component.put` | `component.put` | entity component put | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Component.patch` | `component.patch` | entity component patch | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Component.patchField` | `component.field.patch` | component field patch | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Component.delete` | `component.delete` | entity component delete | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Component.setOverride` | `prefab.override.mutate` | prefab component override | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Script.applySemanticPatch` | `script.semantic_patch.apply` | script behavior edit | yes | yes | normal | `script.semantic_patch.apply` | `shooter`<br>`collector`<br>`door_trigger`<br>`timer`<br>`score_win_state`<br>`basic_multiplayer_interaction` | `check:ai-mcp-sdk-authoring-parity` |
| sdk | `Material.applySemanticPatch` | `material.semantic_patch.apply` | material appearance edit | yes | yes | normal | `material.semantic_patch.apply` |  | `check:material-ai-mcp-sdk-parity` |
| sdk | `Project.applySmartAssetPackage` | `blueprint.package.apply` | smart asset package apply | yes | yes | normal |  |  | `check:ai-mcp-sdk-authoring-parity` |

## Scenario Helpers

| Helper | Title | Operations | Semantic Patch Ops | Proof |
| --- | --- | --- | --- | --- |
| `shooter` | Shooter Intent Helper | `script.semantic_patch.apply` | `addActionHandler`<br>`spawnEntityFromTemplate`<br>`emitCustomEvent`<br>`createCustomEventHandler` | ir: yes<br>source: yes<br>visual: yes<br>runtime: yes<br>playwright: yes |
| `collector` | Collector Intent Helper | `script.semantic_patch.apply` | `addTickHandler`<br>`findEntitiesByTag`<br>`forEachEntityInResult`<br>`despawnEntity`<br>`incrementNumericState`<br>`declareWinCondition` | ir: yes<br>source: yes<br>visual: yes<br>runtime: yes<br>playwright: yes |
| `door_trigger` | Door Trigger Helper | `script.semantic_patch.apply`<br>`component.patch` | `addTriggerHandler`<br>`emitCustomEvent` | ir: yes<br>source: yes<br>visual: yes<br>runtime: no<br>playwright: no |
| `timer` | Timer Helper | `script.semantic_patch.apply` | `addTimerHandler`<br>`emitCustomEvent` | ir: yes<br>source: yes<br>visual: yes<br>runtime: no<br>playwright: no |
| `score_win_state` | Score And Win State Helper | `script.semantic_patch.apply` | `addTickHandler`<br>`incrementNumericState`<br>`findEntitiesByTag`<br>`declareWinCondition` | ir: yes<br>source: yes<br>visual: yes<br>runtime: yes<br>playwright: yes |
| `basic_multiplayer_interaction` | Basic Multiplayer Interaction Helper | `script.semantic_patch.apply` | `createCustomEventHandler`<br>`addActionHandler`<br>`emitCustomEvent` | ir: yes<br>source: yes<br>visual: yes<br>runtime: no<br>playwright: no |
