Overview
A proposal records the row version or row hash that existed when the model requested the change. The runner later includes that expected version in the guarded writeback predicate.
If the row changed after the proposal was created, affected_rows is zero. The runner treats that as conflict, records a terminal receipt, and leaves the source database unchanged.
This is a database-state guarantee, not an MCP annotation hint. The model can request a stale change, but the trusted runner refuses to commit it.
Developer notes
- Configure an updated_at/version column or explicit row-hash guard.
- Treat affected_rows = 0 as conflict.
- Treat affected_rows > 1 as a safety failure.
- Show conflict as a successful safety outcome, not a silent retry loop.