Why the Agent Edits Through Tools Instead of Blobs

When an agent edits a course, the visible request may be as simple as “change the example on page three.” The underlying failure can be much less simple: the model may target the wrong course, two edits may read the same old snapshot, or a background media job may finish after a newer page revision. This chapter diagnoses those failures and explains why OpenMAIC uses owner-scoped, typed tools and serialized document writers instead of letting the model replace an opaque course blob.

The lost-update symptom and the typed-tool diagnosis

An opaque blob hides the operation being requested. If the model sends back a whole course document, the storage layer has to accept a large replacement even when the user wanted one small change. The write may contain a stale copy of every unrelated scene. It may also carry an identifier supplied by the model rather than an identity established by the server. A successful response would not prove that the intended page changed or that another user's course was untouched.

OpenMAIC's agent surface breaks that operation into typed tools. The agent can read a stage, inspect a scene or outline, search the stage, patch a specific path, generate one page, change deck structure, import a presentation, or request media. The tool parameters describe the operation the runtime is prepared to validate. A targeted patch can therefore say which course, scene, and content path it intends to change instead of replacing every field that happened to be in the model's context.

The stage identifier is not treated as proof of ownership. It is an address that the server checks. Before a stage-bearing tool touches the store, the runner probes whether the stage belongs to the session owner and refuses foreign, missing, or tombstoned targets with a generic not-yours response. The owner identity is captured outside the model-visible parameters. This matters because a model can generate a plausible identifier, but it cannot be allowed to choose the security principal that identifier will be evaluated against.

flowchart LR A["Model tool intent"] --> B["Declared stageId"] B --> C{"Owner access probe"} C -->|refused| D["No store write"] C -->|owned| E["Typed read or minimal patch"] E --> F["Sequential writer scheduling"] F --> G["Validate and atomically write document"] G --> H["Durable checkpoint"] E --> I["Detached media job"] I --> J["Stage mutation fence"] J --> G

The owner probe and the typed operation solve different problems. The probe answers “may this session work on this stage?” The tool schema answers “what operation is being attempted?” The document store then validates the resulting stage or scene and enforces its own version and JSON boundaries. No single layer has to trust the model's text as an authorization decision or as a complete document replacement.

The distinction between reading and mutating is deliberate.