@Nick Smith I'm familiar with some work in this area.
I've been working on a type system for a language called Datafun (
http://www.rntz.net/datafun) which enforces monotonicity, and monotonicity turns out to be related to eventual consistency in distributed and concurrent systems (see
http://bloom-lang.net/calm/ and Lindsey Kuper's work on LVars). The idea is to only permit
increasing changes, so the ordering on a type describes how things of that type may change. Kevin Clancy, Heather Miller, & al. have applied a similar type system to distributed programming with CRDTs (
https://infoscience.epfl.ch/record/231867/files/monotonicity-types.pdf).
Along slightly different lines, there's a
lot of work in incremental computation, which implicitly has some notion of
change underlying it. The most popular work here is in FRP systems or in self-adjusting computation (eg. the Incremental library for OCaml). However, the work I'm most familiar with, and which makes the notion of
changes as a data type of their own explicit, is the incremental λ-calculus (
https://www.informatik.uni-marburg.de/~pgiarrusso/ILC/ and
https://www.informatik.uni-marburg.de/~pgiarrusso/papers/pldi14-ilc-author-final.pdf). I've adapted this approach to handle Datafun's type system, but this isn't published in its entirety yet (sometime in the next year).
However, neither of these (yet!) explicitly accounts for reasoning about when changes can/can't be reordered. (In the case of CRDTs, the whole point is that changes can
always be reordered, which is a handy property but can require a lot of cleverness to achieve.)