Versions and conflicts
The version chain, the stale-base ritual, and why humans win by default.
A hosted vos has one version chain. Agent pushes and human studio saves are peers on it: either may change the other's work, there is no review state and no approval gesture, and rendering always picks a version, never a status. Two guards keep that safe.
The stale-base ritual
Every push carries the version it was based on (baseVersionId, tracked for
you in vos.json). If the head moved since you last read it, the push is
rejected, and the rejection carries exactly what you missed:
409 stale_base
currentVersion: { ... }
changes: [ { versionId, origin, label, note, summary, ops } ]
protected: ["speed", ...]The ritual: read the changelog, re-apply your edit on top of the new head, push again with the fresh base. Pushing without a base to skip the guard throws away the human's work; do not.
Protected nodes
A node the human touched in the studio since your last push (a zoom span, a param key, a data key, a code function) rejects your writes:
409 protected_conflict
nodes: ["speed"]Humans win by default. Keep their values and re-push without touching those
nodes. Pass an override (--override speed, or "overrides": ["speed"] over
HTTP) only when the user's instruction targets that exact node: "make it
faster" clears an override on speed; "general polish" never does.
Protection expires once you push. It means "do not undo what the human just did", not "frozen forever".
Restore
History never mutates. Restoring an earlier version copies it forward as a new head version:
POST /api/vos/{id}/versions { "restoreOf": "<versionId>" }The restored version keeps its own thumbnail and document; nothing in between is lost.
Related
- Push and pull for the loop these guards protect.
- Voses and versions for the full HTTP shapes.