capabilities.materialize = true. All three functions are required, and
registration refuses the capability without any of them.
This is what migration and cross-server deployment run on.
PrepareMaterialize
Phase 1. Answers every question that can be answered without writing. Is this record
mine? Is the target usable? Is the model installed?
It is called for previews, so it runs often and must be cheap.
accepted
Optionally with
orientation, preview and warnings.refused
Requires
code ("unsupported" or "invalid") and a non-empty reason. A bare
{ ok = false } is a contract failure, not a refusal.source record it was given. That record is a defensive copy and
is read-only.
preview
An optional tagged union describing what to draw as a ghost:
Returning nothing is fine. An adapter that offers no preview gets a point marker,
silently. Most domains have nothing to draw and that is not a mistake.
kind is required when you do return one. Omitting it is not treated as “model with no
model”: an adapter that forgot the field and an adapter whose domain has no model need
different answers.
Numbers are clamped rather than trusted: radius to 1 to 512, skin to 0 to 255,
coordinates to the world half-extent, and a model path is validated. A value outside those is
corrected silently. A malformed descriptor (a bad model path, mins above maxs, an
unknown kind) is downgraded to a point marker with a warning naming your adapter, never
refused: a cosmetic mistake must not block a migration.
warnings
{ ok = false, code, reason } for anything that will not work.
Materialize
Phase 2. Creates exactly one object, or none.
identity is required, and its source and scope must come from the declared vocabularies.
Returning just ok and localId is a contract failure.
transform may be nil
If your records carry no transform, neither does the argument. An adapter for a positionless
domain that indexes transform.pos errors on every real create, so guard it:
ReleaseMaterialized
Undoes exactly one materialization from the running operation. It is not a general delete.
materialize without it.
Note it takes no ctx argument, unlike the other two.
Where this is used
Post-restore verification asks
PrepareProperties for an adapter that declares properties,
and PrepareMaterialize otherwise. If you declare both, return your orientation from both.